如何在Hibernate中解决Snapshot隔离事务中止错误

时间:2017-09-17 05:56:13

标签: java sql-server hibernate jpa transactions

我们正在使用hibernate来更新表的值,然后我得到了以下错误

org.hibernate.engine.jdbc.spi.SqlExceptionHelper | Snapshot isolation transaction aborted due to update conflict. You cannot use snapshot isolation to access table 'dev.TASKS' directly or indirectly in database 'DEV' to update, delete, or insert the row that has been modified or deleted by another transaction. Retry the transaction or change the isolation level for the update/delete statement.

我们使用hibernate 4.3.11和SQLServer 2014作为我们的数据库。

如何解决此错误?

1 个答案:

答案 0 :(得分:0)

为防止出现异常,数据库有两个选项:

  1. 通过使用锁定可以防止它们。
  2. 它可以允许冲突,但需要在事务提交时检测它们。
  3. 传统上,2PL (Two-Phase Locking)是提供严格可串行性的事实标准。但是,虽然这可以防止所有类型的现象,但它不会扩展。

    由于扩展问题,数据库选择了锁定较少的并发控制机制,如MVCC。但是在MVCC中,允许并发事务修改先前读过的记录。并且,当您尝试提交时,您将获得事务中止。

    因此,您可以通过两种方式解决问题:

    1. 如果并发性较低,则可以像JPA PESSIMISTIC_READ and PESSIMISTIC_WRITE一样使用悲观锁定。一旦获得了需要更改的实体的锁定,其他任何事务都无法对其进行修改,因此他们必须等待您释放锁定。
    2. 您可以按例外的建议,通过重试来完成。
    3. 然而,重试更棘手。如果您遇到约束违规,或者只有在某些行不修改时才进行交易,则无法重试。

      然而,重启工作流程并不像听起来那么糟糕。这是prevent a lost update over multiple physical database transactions的唯一途径。

      所以,尽管Hibernate提供一个神奇地解决这个问题的设置会很棒,但这样做是错误的。交易中止的原因是to avoid breaking ACID guarantees

      因此,您应该查看冲突发生的原因,并确定锁定或重试工作流是否更适合您的特定应用程序用例。