如果我打开一个事务,并将可能会在try-catch块中抛出OLE的代码放入,我是否必须重新启动事务? 我的回答是肯定的,但我似乎无法找到任何确认......
我的代码基本上是这样的:
//start a hibernate transaction here
try
{
//do things that are very likely to throw OLE
}
catch (Exception exc)
{
//just log it and do nothing else
}
//do something else that needs a hibernate session here (*)
所以当我在(*)时,看起来我需要检查交易是否仍然有效?
答案 0 :(得分:1)
如果Session抛出异常,包括任何SQLException, 立即回滚数据库事务,调用Session.close() 并丢弃Session实例。 Session的某些方法不会 使会话保持一致状态。 没有异常抛出 Hibernate可以被视为可恢复的。确保会话将 通过在finally块中调用close()来关闭。
来自:http://docs.oracle.com/javaee/6/api/javax/persistence/OptimisticLockException.html
当乐观锁定冲突时由持久性提供程序抛出 发生。此异常可能作为API调用的一部分抛出,即刷新 或者在提交时。 当前交易(如果有交易)将是 标记为回滚。
所以是的,你应该关闭会话,然后再试一次。
答案 1 :(得分:0)
这是您在JPA规范中可以找到的关于OptimisticLockException
:
为了完整起见,这里是规范中相关部分的副本:
(我无法提供具体的链接,因为该文档仅以.pdf格式here提供)。
3.4.5 OptimisticLockException
提供程序实现可能会延迟写入数据库,直到事务结束,这与锁定模式和刷新模式设置一致。在这种情况下,在提交时间之前可能不会发生乐观锁定检查,并且可能在提交的“完成前”阶段抛出OptimisticLockException。如果必须由应用程序捕获或处理OptimisticLockException,则应用程序应使用flush方法强制进行数据库写入。这将允许应用程序捕获并处理乐观锁定异常。
OptimisticLockException提供了一个API来返回导致引发异常的对象。每次抛出异常时都不保证对象引用存在,但只要持久性提供程序可以提供它,就应该提供对象引用。应用程序不能依赖此对象。
在某些情况下,当跨越VM边界时,将抛出另一个异常(例如RemoteException)并抛出OptimisticLockException。可以在包装的异常中引用的实体应该实现Serializable,以便编组不会失败。
OptimisticLockException总是会导致事务被标记为回滚。
刷新对象或在新的事务上下文中重新加载对象,然后重试事务是对OptimisticLockException的潜在响应。