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

3

我的Spring Boot应用程序中的服务方法被多个线程访问,其中一个线程正在修改数据库中的数据。

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

在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()方法,但没有成功。


2
你的数据库支持哪些隔离级别?更重要的是,为什么你想让另一个线程读取未提交的数据?直接提交不是更好吗? - takteek
1
如果您需要访问第一个线程修改的数据,则您的事务会相互依赖。READ UNCOMMITTED 对此无济于事。您正在写入/读取什么类型的数据,为什么需要在提交之前访问它? - Kayaman
实际上,在第一个线程中,我在数据库中的特定数据上放了一个锁。这样,当一个线程访问它时,其他线程就不能访问它。在我的方法中,首先获取未锁定的数据,并为它们加锁并提交到数据库。这样,其他线程就不会选择那些条目。但不幸的是,它们正在选择相同的条目,因为它们还没有提交到数据库。 - Chanaka NZ
我正在使用PostgreSQL数据库,它支持READ_UNCOMMITTED隔离级别。请帮我解决这个问题,我已经陷入了困境。 - Chanaka NZ
你如何在数据库中“对特定数据进行加锁”? - Jens Schauder
1个回答

2
您混淆了隔离级别和锁定。
隔离级别为`READ_UNCOMMITTED`允许其他事务在第一个事务提交之前看到其写入的内容。它不需要这种情况发生,也不影响锁定。但根据您的评论,您真正想要实现的是以正确的方式锁定数据库行,使其他人无法访问它们。
使用JPA的方法是使用适当的锁定模式查询数据:
引用: 锁定模式可以通过EntityManager lock方法、EntityManager、Query和TypedQuery接口的方法以及NamedQuery注释来指定。
(3.4.4 来自 JPA规范)
您可能对“悲观”变体感兴趣,它可以防止其他事务在锁定的行未提交(因此锁定未释放)之前读取它们。
如果事务T1在一个对象上调用lock(entity, LockModeType.PESSIMISTIC_READ)或lock(entity, LockModeType.PESSIMISTIC_WRITE),实体管理器必须确保以下两种现象都不会发生:
P1(脏读):事务T1修改一行数据。另一个事务T2在T1提交或回滚之前读取该行并获取了修改后的值。
P2(不可重复读):事务T1读取一行数据。另一个事务T2在T1提交或回滚之前修改或删除了该行。

(来自JPA规范的3.4.4.2节)

您可以通过使用@Lock注释在Spring Data JPA中使用这些锁定模式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接