论坛首页 Java企业应用论坛

请教JTA中跨数据库事备的实现原理

浏览 19930 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2004-07-19  
我尚未使用过JTA,但就其所实现的跨数据库事务,有几点疑惑:
假设存在子系统A,数据库DB_A;子系统B,数据库DB_B,数据库之间物理隔离。

假如要实现这样的功能:
B从A获得数据,更新B中的数据库,更新完成后更新A中的数据库。那么这样的操作用JTA如何保证100%正确?

我的不解之处是:
数据库A和B肯定都要实现各自的begin transaction和commit transaction。
假设A先commit transaction,成功之后B再commit,那么如果B在commit时出错,如何让Arollback?反之亦然。

我原来做过的一套系统是用ASP/PHP实现的,对跨数据库事务的处理采用的是消息传递机制,即A begin->B begin-> B预更新->A预更新->B commit->A Commit。整套消息机制建立在任何一个环节都没有发生错误的情况下。当然这样无法完全保证事务的正确性,比如在A commit时恰好server、数据库、网络连接出现问题等。

盼答案。
注:在google上尝试搜索了一下,没找到相关内容的介绍。
   发表时间:2004-07-19  
这是标准的两阶段提交来实现分布式事务。

http://www.vermicelli.pasta.cs.uit.no/ipv6/students/andrer/doc/html/node18.html
0 请登录后投票
   发表时间:2004-07-20  
也就是说,仍然是无法保证100%的事务完整?
前提仍然是在最后一个事务提交时,消息传递出去之后必须保证事务提交成功。如果最后一个事务没有提交成功,但前一个事务已经提交,还是没有办法回滚的。
0 请登录后投票
   发表时间:2004-07-20  
abcd123efg123 写道
也就是说,仍然是无法保证100%的事务完整?
前提仍然是在最后一个事务提交时,消息传递出去之后必须保证事务提交成功。如果最后一个事务没有提交成功,但前一个事务已经提交,还是没有办法回滚的。


你说的这种情况在两阶段提交中是有相应处理的。在事务处理过程中会有详细的Log记录事务处理过程,当后一个事务失败时,可以通过Log恢复数据,以保证数据的完整性。
0 请登录后投票
   发表时间:2004-07-20  
亦即是说,JTA虽然提供了跨数据库的事务处理,但仍然需要人工监控事务处理的日志,对异常情况进行手工处理。
当然这种情况发生的几率很小。
0 请登录后投票
   发表时间:2004-07-20  
欠可靠的网络和系统中,不论使用哪种协议,完全的可靠性是达不到的。但是两阶段提交能够解决绝大部分问题。
0 请登录后投票
   发表时间:2004-07-21  
对于两阶段提交协议,具体的根据事务处理日志恢复数据的处理不清楚,又没有那位熟悉的人出来解释一下?是不是要有数据库的支持?
0 请登录后投票
   发表时间:2004-07-21  
这个问题我以前也头痛过,不过后来就不想它了,反正我从来没用到要二个数据库的情况,范不着和自已过不去。我想完全的不出差错实在太过复杂,只用那个二阶段那个是不行的。
0 请登录后投票
   发表时间:2004-08-18  
两段提交事务并不是JTA特有的

只要这些资源遵从XA的规范,就可以保证事务的原子性

昏倒。。。怎么会想到需要人工去盯着事务日志文件。

难道有听说过我们需要不停的扫描数据库事务日志文件以查看事务
是否执行成功么,两段事务的实现对使用者来说是透明的。

//一家之言
0 请登录后投票
   发表时间:2004-08-18  
我根据自己的经验谈一下个人看法。这是一个非常复杂的话题。三言两语可能说不清楚。

1. Transaction 分两种,Local Transaction 和 Global Transaction。
  涉及到一个Connection的Commit,称为Local Transaction。
  涉及到多个Connection的Commit,称为Global Transaction。
楼主提到的是,Global Transaction.

2. Global Transaction 需要XA接口(包括在JTA里面)的支持。

import javax.sql.XAConnection;
import javax.transaction.xa.Xid;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.XAException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;

其中的
javax.sql.XAConnection;
javax.transaction.xa.Xid;
javax.transaction.xa.XAResource;

这些XA接口的实现,需要数据库的JDBC提供。
数据库本身要支持XA。数据库的JDBC也要提供XA的实现。

Oracle, Sybase, DB2, SQL Server等大型数据库才支持XA, 支持Global Transaction。
My SQL 连Local Transaction都支持不好,更别说Global Transation了。

3. XA需要两阶段提交 -- prepare 和 commit.
假设有两个Connection,  con1, con2, 大体的过程如下,

con1 = XAResouce1.getConnection...
con2 = XAResouce2.getConnection...

con1 do some thing.
con2 do some thing.
after they finish.

pre1 = XAResouce1.prepare();
pre2 = XAResouce2.prepare();

if( both pre1 and pre2 are OK){
   XAResouce1 and 2 commit
}else {
   XAResouce1 and 2 rollback
}

前面有人讲了,在XAResouce1 and 2 commit的时候,
可能XAResouce1 commit() 成功了,XAResouce2 commit()失败了。
这时候,会抛出一个 “启发式异常”。程序可以处理这个异常。比如,XAResouce.recover()之类。
但一般情况下,还真没别的办法,需要数据管理员根据数据操作日志 undo所有的操作,或者恢复数据备份。
有的数据库在进行数据操作的时候,会生成一个“反操作”日志。比如,insert 对 delete, 等。

4. TransactionManager的实现能够处理多个XAResouce(一个XAResouce list)的情况。
比如Tyrex。或JBoss等EJB Server的Transaction实现代码。

个人理解。可能有偏差。请指正。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics