我有一个事务,在这个事务中,要在oracle更改一条记录,然后又在sqlserver中更改一条记录,怎样能保证这两个更改的原子性?????

解决方案 »

  1.   

    这个问题不使用JTA也可以
    一般JTA最好不要管理数据库的事务。oracle和sqlserver肯定是两个连接
    那么你就这么做
    try {
    conn1.setAutoCommit(flase);
    conn2.setAutoCommit(flase);
    //do somthing
    conn1.commit();
    conn2.commit();
    } catch(Exception e) {
    conn1.rollBack();
    conn2.rollBack();
    }
    一旦发生异常,同时回滚两个失误
      

  2.   

    晕!
    为什么放着JTA不用去写这些代码我不明白JTA有什么不好
      

  3.   

    那段代码有问题,如果第一个COMMIT运行了,第二个报错,第一个怎么回滚?
    要用到JTA的两阶段提交的,实在不行在数据库建DBLINK或者别的东西,反正就是就是在一个连接上读两个库的数据
      

  4.   

    原文供参考Two Phase Commit (2PC)1‧start(Xid) - enlist the resource as part of the transaction 
    2‧end(Xid) - tell the resource that no more transactional work is coming its way 
    3‧prepare(Xid) - prepare for commiting. The resource can respond "OK" or "oh no!". The latter indicates that the whole global transaction should be rolled back. 
    4‧commit(Xid) - Really commit. For practical purposes, you can think of start() as saying "OK, all future work should be recorded as part of this transaction until I tell you otherwise". The end() call is the "otherwise" - signals to the resource to stop recording. All of the work between the calls should be held in a bucket somewhere keyed by the Xid.The latter two calls - prepare() and commit() - are the real part of 2PC. Once all the work is done in a transaction, the transaction manager first calls all the resource managers with a prepare() call. This means "get ready to commit, but don't do it yet!". At this point, all resources get to vote on the outcome of the transaction. If any resource votes no, the transaction rolls back. If they all vote yes, the transaction will be commited. If the latter occurs, the transaction manager then calls commit() on all of the resources.Differentiating between the start()/end() bits and the prepare()/commit() bits can be a little confusing to people who aren't knee-deep in XA. Don't worry about it - it confuses most everyone the first time through. Think of it this way: start() and end() is the transaction manager's way of letting the XAResource know when to flip on transactional recording and turn it off again. Before start(), you're not in a transaction. After end(), you're also not in a transaction - but you have to remember everything you did between start() and end(), tag it with the Xid, and hold onto that information in a bucket somewhere. At this point, post-end(), you've done a bunch of work but not unleashed it globally anywhere. The unleashing is where prepare() and commit() come into play. The prepare() part makes sure everyone thinks the transaction is kosher, the commit() part does the final bit of unleashing of all the transactional work out into the wild.
      

  5.   

    看你是分布式数据库
    这个当然可以用JTA管理,为什么不用?启动transaction,做你的两个操作,最后commit.错误rollback
    jdbc的可以不启动, 如果想保证代码移植也可以加上,但你的操作必须控制在jta大事务当中,如果你
    是用EJB处理业务,设置默认required事务属性就可以了。
      

  6.   

    我现在想知道的是,jta是怎么实现两阶段提交的,原理
    哪位高人知道?
      

  7.   

    JTA在weblogic环境下,就是用
    context.lookup("javax.transaction.UserTransaction");
    得到事务。
    如果是jboss需要自己配置一个javax.transaction.UserTransaction的resource然后就是beginTransaction()
    commit()
    rollback()
    之类的方法,说白了也没什么我们用这个就可以管理所有逻辑功能的事务了
      

  8.   

    --那段代码有问题,如果第一个COMMIT运行了,第二个报错,第一个怎么回滚?
    --要用到JTA的两阶段提交的,实在不行在数据库建DBLINK或者别的东西,反正就是就是在一个连接上---读两个库的数据
    其实主要原因不是第一个提交成功,第2个失败,而是提交第二个的时候网络断了,会出问题真正到了提交这一步,数据操作不会出问题的.
      

  9.   

    楼主可以看看第四期的《程序员》杂志
    里面有一篇《探讨与比较EJB和COM+的事务管理框架》