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

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

我在 Spring Boot Application 中的服务方法被多个线程访问,一个线程正在修改 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() 方法,但没有成功。

最佳答案

您混淆了隔离级别和锁。

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

执行此操作的 JPA 方法是使用适当的锁定模式查询数据:

Lock modes can be specified by means of the EntityManager lock method, the methods of the EntityManager, Query, and TypedQuery interfaces that allow lock modes to be specified, and the NamedQuery annotation.

(来自 JPA Specification 的 3.4.4)

您可能对“悲观”变体感兴趣,它会阻止另一个事务在锁定的行被提交之前读取它们(因此锁定被释放)

If transaction T1 calls lock(entity, LockModeType.PESSIMISTIC_READ) or lock(entity, LockModeType.PESSIMISTIC_WRITE)onanobject,the entitymanager must ensure that neither of the following phenomena can occur:

  • P1 (Dirty read): Transaction T1 modifies a row. Another transaction T2 then reads that row and obtains the modified value, before T1 has committed or rolled back.
  • P2 (Non-repeatable read): Transaction T1 reads a row. Another transaction T2 then modifies or deletes that row, before T1 has committed or rolled back.

(来自 JPA Specification 的 3.4.4.2)

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

关于java - 读取 Spring JPA Repository 中未提交的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46067867/

相关文章:

Java Spring : Attribute 'time-unit' is not allowed to appear in element 'int:poller'

coldfusion - 我什么时候应该在 ColdFusion 中使用作用域锁定(应用程序、服务器等)与命名锁定?

Haskell: 'atomicModifyIORef' 是如何工作的?

Java : Replace \"with " and\/with/

java - 使用@Aspect更改方法签名

java - 如何授权Spring应用的服务层?

mysql - Laravel 悲观锁定无法阻止多个重复请求中未提交行上的 SELECT

java - 如何使用 XML 将 Jetty 请求日志设置为默认时区

java - 无法在 NIO 中获取输出

java - Kotlin 字符串最大长度? (带有长字符串的 Kotlin 文件无法编译)