打开的事务看不到另一个事务提交的数据
Posted
技术标签:
【中文标题】打开的事务看不到另一个事务提交的数据【英文标题】:Open transaction cannot see committed data by another transaction 【发布时间】:2021-08-28 03:50:26 【问题描述】:我有一个 Spring Boot 应用程序,在这个 REST 调用中调用了一个 REST 服务,完成了两个单独的 DB 操作(正在使用 Spring Data JPA)。第一个更新一些数据库表,第二个从所述表中读取并执行一些操作。
@GetMapping("/process")
public void process()
service1.updateValues();//updates the values
service2.readValuesAndProcess();//reads those updated values and execute some logic and persist at the end
现在的问题是;
第二种方法似乎没有读取在第一种方法中更新的更新值,而是以某种方式读取更新之前的值。这两个方法都是@Transactional
,实体是@versioned
,当调用保存操作时会抛出ObjectOptimisticLockingFailureException
。
在 application.properties 中 spring.jpa.open-in-view
属性为 true,当我将其更改为 false 时,一切都按预期工作,但我不能保证我不会在其他地方得到 lazyInitializationException
。
我尝试将事务方法传播更改为 REQUIRES_NEW,但没有任何变化。
【问题讨论】:
如何更新 updateValues() 方法中的值?如果您使用 spring.jpa.open-in-view = true,那么在您的请求中,只有一个实体管理器用于您的所有语句。因此,如果您保存的对象仍在实体管理器缓存中,则可能不会从数据库中重新加载它。顺便说一句, spring.jpa.open-in-view = true 被认为是反模式。看到这个:***.com/questions/30549489/… 是的,我们使用 spring.jpa.open-in-view = true,您的见解是正确的。实体是通过来自另一个实体的@onetoone 关系加载的,并且不会使用 save 进行更新,而是使用自定义 hql 查询进行更新,因此不会更新一级缓存。因此,当执行第二次选择时,将从一级缓存中获取实体。 【参考方案1】:updateValues
的更新进展如何?并发用户的代码线程安全吗?
丢失更新可能会导致JPA
抛出ObjectOptimisticLockingFailureException
,这是一件好事。
有关乐观锁定的更多信息,请阅读此内容:Optimistic Locking in JPA | Baeldung。
【讨论】:
【参考方案2】:如果 updateValues() 被注释为@Transactional,它应该可以工作。在 updatevalues() 结束时,更改将在春季实际提交到数据库
【讨论】:
以上是关于打开的事务看不到另一个事务提交的数据的主要内容,如果未能解决你的问题,请参考以下文章
一个事务中先插入数据,然后再查询所有数据,能查到刚才的记录吗
求数据库大神,mysql事务隔离级别repeatable-read 详解