【问题标题】:How are the Spring @Transactional and the Hibernate @LockMode annotations relatedSpring @Transactional 和 Hibernate @LockMode 注释如何相关
【发布时间】:2016-10-25 03:24:21
【问题描述】:

我想知道事务和锁的关系。

更具体地说,Spring 的@Transactional 与 Hibernate 的 LockMode 有什么关系。 https://docs.jboss.org/hibernate/orm/4.0/devguide/en-US/html/ch05.htmlhttp://docs.spring.io/autorepo/docs/spring/4.2.x/spring-framework-reference/html/transaction.html

如果我在创建会话对象时没有指定任何锁,并使用@TransactionalreadOnly 作为false,我是在使用悲观并发控制吗?

如果有人能告诉我(乐观/悲观)并发控制和事务之间的关系,那将是一个很大的帮助。

谢谢, 维韦克

【问题讨论】:

    标签: java spring hibernate transactions locking


    【解决方案1】:

    @Transactional@LockMode 注释之间没有直接关系。

    @Transactional 用于标记 RESOURCE_LOCAL 或 JTA 事务的显式边界。您需要它的原因是每个数据库语句都在事务上下文中执行,并且,如果您不设置事务边界,您将获得每个语句一个事务或自动提交。

    另一方面,@LockModeType 用于设置显式锁定选项。如果不设置,会使用隐式锁定机制:

    • 在 2PL 和 MVCC 数据库引擎上的每个修改行上都会获取隐式锁。如果您在 Serializable 上使用可重复读取,则会在 2PL 引擎上的读取记录上获取共享锁。
    • 如果您定义了@Version 属性,则将使用隐式乐观锁定机制。

    所以,@LockModeType 用于显式设置锁定选项,您可以有以下选项:

    PESSIMISTIC 锁定模式将始终在与锁定实体关联的表行上获取数据库锁定。

    还有显式的乐观锁策略:

    OPTIMISTIC 锁定模式旨在为您提供一种提升实体版本的方法,即使实体在当前运行的持久性上下文中没有更改。当您需要使用其父实体版本来协调多个子实体时,这是一种非常有用的机制。

    我在此答案中提供的链接中有很多示例,因此请花点时间阅读所有示例,您将更详细地了解所有这些概念。

    【讨论】:

    • 我理解正确吗 - 仅通过 @Version 注释设置了隐式锁定?否则必须显式使用?
    • 我不明白你的问题。无论是否使用乐观锁定,隐式锁定都与任何行更改相关联。
    • 您列出了隐式锁的可能性,第一个点以“在每个修改的行上获取显式锁......”开头。你的意思是“隐式锁”,对吧?或者更确切地说是排他性的?
    • 好收获。我重组了答案以使其更清晰。
    【解决方案2】:

    Spring 的 @Transactional 和 Hibernate 的 LockMode 类是不同的。

    Spring 事务管理

    @Transactional 是用于声明式事务管理的 Spring 注释,即定义在数据库事务中一起执行哪些 SQL 语句。例如,如果您尝试在只读事务中插入行,则使用 readOnly 属性允许 Spring 抛出异常。

    然而,关于锁定,您很可能会使用读/写 (readOnly = false) 事务,因为您将尝试修改数据。

    悲观锁定

    Hibernate 的LockMode 用于悲观锁定,例如LockMode.UPGRADE实际上执行了SELECT...FOR UPDATE语句,并锁定了数据库中实体对应的行。

    悲观锁假设并发事务会发生冲突 相互之间,并且需要资源在它们被锁定后被锁定 读取并仅在应用程序完成使用后解锁 数据。

    乐观锁定

    Hibernate 中的乐观并发控制通常使用数据库中的版本或时间戳列。这里的想法是,如果多个事务尝试同时修改一行,除了第一个提交的事务之外的所有事务都将检测到版本号已更改并执行回滚。

    乐观锁假设多个事务可以完成 不会相互影响,因此交易可以 在不锁定它们影响的数据资源的情况下继续。前 提交时,每个事务都验证没有其他事务具有 修改了它的数据。如果检查显示有冲突的修改,则 提交事务回滚。

    以上引用来自:https://docs.jboss.org/hibernate/orm/4.0/devguide/en-US/html/ch05.html

    【讨论】:

    • 谢谢@CK1。我已经知道你提到的。我不知道什么时候使用。我知道 Spring@Transactional 是用于事务管理的,而且大多是在服务方法上注解的。通过使用@Transactional,我可以管理并发事务,那么为什么需要LockMode@Version。您能否通过每个用例或示例进行解释。
    • 当冲突频繁发生时使用悲观锁定。当预计不会发生冲突时使用乐观锁定。当两个或多个数据库事务同时修改同一行时,需要锁定。
    猜你喜欢
    • 2018-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-19
    • 2018-01-22
    • 2013-07-20
    • 2014-07-15
    • 1970-01-01
    相关资源
    最近更新 更多