我们有一个系统,我们偶尔会得到一个乐观的锁定异常。我们已经在代码中解决了这个问题,但是现在我正在查看JPA 2,并看到它有一个注释(@Version)来处理这个问题。
我们遇到的问题是,多个事务正在处理一个表,而对于一个完整的表锁,这会导致乐观锁定异常,即使没有对相同的记录进行更改。
我们在JBoss 4.2服务器上使用hibernate,数据库可以是MySQL,也可以是server。
如果我们改为使用@Version,这会在两个数据库上强制行锁,还是仍然会看到由全表锁引起的乐观锁定异常?
编辑:
我们实际看到的不是乐观锁定错误,而是死锁:
SQLServerException:事务与另一个进程在锁定资源上陷入僵局,并被选择为死锁受害者。重新运行事务。
我们在代码中处理这个问题,但我想知道@Version在这种情况下是否有帮助。
至少在其中一种情况下,这种死锁是由表锁引起的,其中两个客户端正在处理自己的数据。
发布于 2013-03-07 14:57:44
这取决于您的SQL语句。当事务由于任何原因而无法获得所需资源的锁时,就会出现乐观锁。这可能是由于表锁或行锁造成的。无所谓。
如果您正在运行需要表锁的SQL查询,那么版本字段就不会有任何进展了。默认情况下,使用行锁。因此,您可能有小表或缺少主键,或者SQL Server在查询中使用表锁还有其他原因。
您应该对生成表锁并试图对其进行调整的查询进行调查。您应该期望偶尔发生锁定,并在应用程序中处理它。
发布于 2013-03-07 15:14:09
可能重复:乐观与悲观锁定
乐观锁定异常几乎总是一个有状态并发问题。例如:两个线程加载完全相同的实体,并行地更改对象,然后保存它。--不管事务的(表或行锁)--当这种情况发生时,您将得到一个乐观的锁定异常(请参阅参考问题)。
我很震惊您的乐观锁定异常w/o @Version,在这种情况下,您可能得到了真正的RDBMS OCC错误,但我对此表示怀疑。最有可能发生的情况是,整个对象被区分到该行(因为您没有指定@Version),在这种情况下,对行的任何更改都会导致乐观锁定异常。请在你的问题上加上例外情况,这样我就不用假设了。
https://stackoverflow.com/questions/15272535
复制相似问题