在提交当前事务之前,hibernate 检查该行的版本时,它应该发出一条 sqlselect语句来获取该行。
假设在发出该select语句后,hibernate 发现行版本没有改变,因此它应该继续提交事务。
我想知道 hibernate 如何确保在选择行和提交当前事务之间的时间段内没有任何其他事务会更新行更改其版本号?休眠可以做的唯一可能的事情似乎是使用悲观锁定的行版本选择Select ... For Update或具有这种隔离级别的事务,它将锁定正在读取的行。
如果我的想法是真的:
那么休眠乐观锁实际上确实对其操作使用了悲观锁,尽管悲观锁被持有的时间很短,因为事务将在此之后立即提交。
否则我们在行版本检查和提交之间有一个很短的时间段,可能会发生竞争条件。
请分享您的想法。
sql hibernate race-condition optimistic-locking pessimistic-locking
我有两个关于 Hibernate 3.3.2.ga 中提供的悲观 LockMode 的问题:
如果我使用锁定模式 UPGRADE 锁定一组行,当您移出事务范围时,锁是否会被释放?如果可以的话,我们可以跨事务加锁解锁吗?
对于以下场景,哪种 LockMode 会很有用
线程 1,尝试获取锁并锁定一组行
线程 2 尝试获取同一组行上的锁(与线程 1 锁定的行相同),此时线程 2 收到异常,指出行已锁定
哪种是最好的悲观 LockMode?
我目前正在使用rails 3 + postgresql做一个悲观的loking.但似乎没有办法确认锁是否正常工作,除非我经历了进行并发测试的麻烦.有没有办法通过控制台测试这个?
例
User.transaction do
u1 = User.find(1, :lock => true)
u2 = User.find(1)
## u2 should not be able to do anything right?
end
Run Code Online (Sandbox Code Playgroud) 根据 JPA 2.1 规范...
锁定模式
PESSIMISTIC_READ、PESSIMISTIC_WRITE、 和PESSIMISTIC_FORCE_INCREMENT用于立即获取长期数据库锁定。
我假设悲观锁总是会SELECT ... FOR UPDATE在数据库上触发 SQL,无论使用什么锁模式。现在三个问题:
SELECT ... FOR UPDATE锁定的行。除了锁定行的事务之外,任何其他事务都不能更新锁定的行吗?我正在尝试使用 select for update 来实现悲观锁定,因为我希望其他线程等待,直到释放所选行上的锁。我所理解的部分是在经历了多个线程Spring JDBC select for update和各种类似的线程之后,如果 select 和 update 发生在同一方法中,因此它们是同一事务的一部分,那么这是可以实现的。
在我的例子中,问题是我有一个用于 DAO 功能的 JAR,其中有一个selectforUpdate方法可用,并且有一个单独的更新方法可用,这两种方法都有一个 finally 块,其中包含
resultSet.close();
statement.close();
connection.close();
Run Code Online (Sandbox Code Playgroud)
现在我正在努力找出是否有一种方法可以从 JAR 外部使用这两种方法,也许可以通过用@Transactional注释来注释我的方法并使其以某种方式工作。因此只有在执行 update 方法后才会释放该锁。
hibernate ×2
java ×2
postgresql ×2
concurrency ×1
jdbc ×1
jpa ×1
locking ×1
mysql ×1
spring ×1
sql ×1
transactions ×1