在Spring JPA Repository中读取未提交的数据

时间:2017-09-06 06:02:52

标签: java spring locking spring-data-jpa spring-transactions

Spring Boot Application中的服务方法由多个线程访问,一个线程正在修改DB中的数据。

当其他线程在第一次提交之前访问数据时,它将不会获得早期线程的db更新。

在stackoverflow上长时间搜索后,我对相关方法使用了以下注释。

import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_UNCOMMITTED)
public void accept(Event<String> event) {}

但是无法实现预期的结果。未在第二个线程中检索未提交的更改。

请帮我解决这个问题。

我使用了实体管理器flush()方法,但没有成功。

1 个答案:

答案 0 :(得分:1)

你正在混淆隔离级别和锁定。

隔离级别READ_UNCOMMITTED 允许其他事务查看您的第一个事务在提交之前写入的内容。它不需要这样做,也不会影响锁。但根据您的意见,您真正希望实现的是以某种方式正确锁定数据库行,以便其他人无法访问它们。

JPA的方法是使用适当的锁定模式查询数据:

  

可以通过EntityManager锁定方法,允许指定锁定模式的EntityManager,Query和TypedQuery接口的方法以及NamedQuery注释来指定锁定模式。

(来自SO Question的3.4.4)

你可能对悲观&#34;感兴趣?防止另一个事务在提交之前读取锁定行(因此锁定已释放)的变体

  

如果事务T1在对象上调用lock(entity,LockModeType.PESSIMISTIC_READ)或lock(entity,LockModeType.PESSIMISTIC_WRITE),则实体管理器必须确保不会发生以下任何现象:

     
      
  • P1(脏读):事务T1修改一行。然后,另一个事务T2在T1已提交或回滚之前读取该行并获取修改后的值。
  •   
  • P2(不可重复读取):事务T1读取一行。然后,另一个事务T2在T1提交或回滚之前修改或删除该行。
  •   

(来自JPA Specification的3.4.4.2)

您可以使用JPA Specification注释将这些锁定模式与Spring Data JPA一起使用。