2014-10-06 58 views
0

我试图用Hibernate保存数据。一切都在同一会话中进行。该逻辑如下:Hibernate事务从另一个事务抛出异常

1)开始交易,并试图保存:

try 
{ 

    session.getTransaction().begin(); 
    session.save(result); 
    session.getTransaction().commit(); 
} 
catch (Exception e) 
{ 
    session.getTransaction().rollback(); 
    throw e; 
} 

2)如果一个新的记录违反完整性约束赶在外包装法例外,打开另一个事务及查询更多数据

catch (ConstraintViolationException e) 
{ 
    if ("23000".equals(e.getSQLException().getSQLState())) 
    { 
    ... 

    session.getTransaction().begin(); 
    Query query = session.createQuery("from Appointment a where a.begin >= :begin and a.end <= :end"); 
    query.setDate("begin", date); 
    query.setDate("end", DateUtils.addDays(date, 1)); 

    List results = query.list(); 
    session.getTransaction().commit(); 

问题是,当第二事务执行query.list它抛出should'be被与前一事务链接异常。

SQLIntegrityConstraintViolationException:ORA-00001:唯一约束

我应该从另一个会话查询数据或者有什么其他的方式来彼此隔离两笔交易?

谢谢!

+0

我想在第二种情况下,当抛出异常并且稍后查询第二个事务时,必须回滚catch块中的第一个事务。目前您刚刚开始第二笔交易时出现错误,因为第一笔交易尚未回滚 – vikeng21 2014-10-06 04:42:52

+0

@ vikeng21,不是真的,第一个模块拥有自己的“catch(Exception e)”,它会回滚第一笔交易。然后它重新抛出一个异常,它被第二个块捕获,第二个事务开始。 – andreybavt 2014-10-06 04:47:18

+0

哦,好吧,它们是代码的相同部分,但是您的异常hirerchy不正确,您的会话对象是全局权限。你可以尝试创建一个新的会话对象,因为我们可以创建会话对象的每个事务。你的异常看起来像插入相关,但你实际上运行一个选择查询不知道为什么你得到它 – vikeng21 2014-10-06 04:56:03

回答

1

,如果你得到一个异常,则不应使用同一个会话,你必须关闭会话,并使用不同的会话你的第二个操作。这是送给Hibernate文档中:

13.2.3 Exception Handling

如果Session抛出异常,包括任何的SQLException, 立即回滚数据库事务,调用Session.close() ,丢弃该Session实例。会话的某些方法不会 使会话保持一致状态。 没有抛出异常Hibernate可以被视为可恢复。通过在finally块中调用close()来确保会话将会关闭 。

0

希望Exception类是所有类型异常的基础,因此如果在它被放置之前它将被捕获并且其余的异常处理被隔离。

+0

在调试器中,我真的首先在'catch(Exception e) {session.getTransaction() .rollback(); 扔e; }' block然后在第二个catch(ConstraintViolationException e)块中。所以我提到的所有代码都是可以访问的。问题在于每笔交易的范围以及为什么它们都是混合的 – andreybavt 2014-10-06 05:07:44

相关问题