在一个方法中同时使用了两种事务,
一个是Hibernate的事务,另一个是jdbc的事务,
请教各位,如何确保其中一个事务提交失败时,另一个事务必需回滚。
例如,jdbc事务提交成功,但hibernate事务提交失败,怎样才能让jdbc事务回滚?或者有什么更好的方式解决这种问题。部分代码:public boolean doAudit() throws Exception {
Session sess = null;
Transaction tx = null;
Connection con = null;
try {
//Hibernate 事务
sess = HibernateCfg.openClearedSession();
tx =  HibernateCfg.beginTransaction(sess);
//jdbc事务
con = DBTools.getConnection();
DBTools.beginTransaction(con);
onAudit(sess, con);
DBTools.commit(con);
HibernateCfg.commit(tx); 
return true;
} catch (Exception e) {
DBTools.rollback(con);
HibernateCfg.rollBack(tx);
} finally {
DBTools.release(con);
}
return false;
}

解决方案 »

  1.   

       首先你的问题有点没说清楚!  jdbc connection 和 hibernate的session 是否共享同一个connection?
    如果是同一个connection 既你的jdbc connection是session 获取的的con,那么你可以在jdbc 操作出现需要回滚的情况下,设置session的是否回滚的状态。  这种情况不属于事物欠套问题。  如果他们获取的 connection 并不是同一个,举个例子,如果你使用spring来配置方法的事物,并设置了事物隔离级别和传播行为(解决事物欠套问题),这个时候如果是 具备事物功能的方法A调用了 同样具备事物功能的方法B,这个时候配置的事物传播行为开始起作用。    详细你可以参考这篇文章,是事物隔离级别和传播行为写的比较清晰的一篇。
        http://www.javaeye.com/topic/78674    里面有伪代码,非常不错。   楼主仔细看下。
      

  2.   

    手写 是没问题的,也可以通过配置事物传播行为来实现你的做法。使用spring的事物模版类,你就没必要自己实现传播行为的事情了。
      

  3.   

    jdbc和hibernate这两个连接不是共享同一个connection, 是连接到两个不同数据库。
      

  4.   

    to xinlan1022我汗!不是事务资源是分开的就一定是分布式事务的。分布式事务的概念不是以resource来区分的。XAResource的接口是通过分布式 TM(transaction Manager)来实现 2PC(2 phase commit)来完成的。着这样的需求属于local transaction的事务嵌套,分布的resource都是由它们的local TMs来管理的。和分布式事务需求还不一样,不要和分布式事务挂上沟了,把简单的问题复杂化。to 楼主不好意思,前面我的回答太草率了,我现在也发现简单的使用spring的事务模板,声明事务传播行为是基于同一个SessionFactory,你这样的需求的确还是自己写传播行为比较好。如果你想写的优雅点,倒是可以复写spring的 AOP模板,两个事务的开启和提交由自己来写,可以把两个事务处理通过两个方法分离。
    即:    AOP
              interceptor before
                //hibernate事务开启,session 资源绑定ThreadLocal hibernate_local
                //jdbc事务开启, connection 资源绑定ThreadLocal jdbc_local
                  
                       target 
                           //hibernate业务处理,保存状态(是否提交或回滚)
                              //jdbc业务处理,保存状态(是否提交或回滚)       
              interceptor after
                //hibernate 根据状态,判断是否需要提交或者回滚
                  //jdbc 根据状态,判断是否需要提交或者回滚楼主不好意思啊。
      

  5.   

    我使用的是Oracle数据库,有两个用户,之前一个是用Hibernate去连接,另一个用jdbc去连接。
    现在直接通过用户去访问另一个数据库就可以了。
    如:update est.ch_room set roomlabel ....我的这个问题可能和你所说的有所出入。
      

  6.   

    我明白你的意思了,跨schema操作。呵呵。变成共享一个connection了。oracle是蛮强大的,以前接触的oracle多,用起来也感觉爽些,
    现在接触symfoware,怀恋oracle啊。