【问题标题】:Hibernate/Spring : Pessimist vs Optimist locking?Hibernate/Spring:悲观与乐观锁定?
【发布时间】:2018-10-22 02:28:49
【问题描述】:
在使用像 Hibernate(使用 Spring 框架)这样的 ORM 工具时,我不确定如何理解锁定和事务。
例如,当您使用 @Transactional 并指定隔离级别时,这是否意味着您正在使用悲观锁定?
你可以同时使用悲观锁和乐观锁吗?
我听说乐观锁定通常更好,但我没有找到很多带有@Version 等内容的项目......大多数时候我总是看到@Transaction Spring 注释被用于管理事务。
谢谢
【问题讨论】:
标签:
sql
spring
hibernate
jpa
spring-data
【解决方案1】:
例如,当您使用 @Transactional 并指定隔离级别时,这是否意味着您正在使用悲观锁定?
不一定。
您可以通过将隔离指定为READ UNCOMMITTED 来指定进行脏读取的方法,如果另一个事务已修改但尚未提交您的方法正在读取的行,您基本上会返回已修改但尚未提交的值。这是因为在此隔离级别下,在读取时不会创建共享读取锁。因此,简而言之,此方法进行基本读取,而无需担心锁定。
你能同时使用悲观锁和乐观锁吗?
绝对的。
如果您的用例要求您需要该行为,您可以要求 Hibernate 对包含 @Version 字段的实体应用悲观锁。
我听说乐观锁定通常更好,但我没有找到很多带有@Version 等内容的项目...大多数时候我总是看到@Transaction Spring 注释被用于管理事务。
我想说,网络上充斥着没有考虑到复杂应用程序中数据一致性的所有内在需求的琐碎示例。这些示例旨在主要说明以下内容优于其对应项
@Transactional
public void doSomeSpecialThing() {
// do your thing here
}
对
public void doSomeSpecialThing() {
entityManager.getTransaction().begin();
try {
// do your thing here
entityManager.getTransaction().commit();
}
catch ( Exception e ) {
if ( entityManager.getTransaction().isActive() ) {
entityManager.getTransaction().rollback();
}
throw e;
}
}
您是否需要在方法的数据访问代码中应用悲观、乐观或两者的组合成为用例特定的需求,而不是一概而论。