锁定老帖子 主题:请教JTA中跨数据库事备的实现原理
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2004-07-19
假设存在子系统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上尝试搜索了一下,没找到相关内容的介绍。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2004-07-19
这是标准的两阶段提交来实现分布式事务。
http://www.vermicelli.pasta.cs.uit.no/ipv6/students/andrer/doc/html/node18.html |
|
返回顶楼 | |
发表时间:2004-07-20
也就是说,仍然是无法保证100%的事务完整?
前提仍然是在最后一个事务提交时,消息传递出去之后必须保证事务提交成功。如果最后一个事务没有提交成功,但前一个事务已经提交,还是没有办法回滚的。 |
|
返回顶楼 | |
发表时间:2004-07-20
abcd123efg123 写道 也就是说,仍然是无法保证100%的事务完整?
前提仍然是在最后一个事务提交时,消息传递出去之后必须保证事务提交成功。如果最后一个事务没有提交成功,但前一个事务已经提交,还是没有办法回滚的。 你说的这种情况在两阶段提交中是有相应处理的。在事务处理过程中会有详细的Log记录事务处理过程,当后一个事务失败时,可以通过Log恢复数据,以保证数据的完整性。 |
|
返回顶楼 | |
发表时间:2004-07-20
亦即是说,JTA虽然提供了跨数据库的事务处理,但仍然需要人工监控事务处理的日志,对异常情况进行手工处理。
当然这种情况发生的几率很小。 |
|
返回顶楼 | |
发表时间:2004-07-20
欠可靠的网络和系统中,不论使用哪种协议,完全的可靠性是达不到的。但是两阶段提交能够解决绝大部分问题。
|
|
返回顶楼 | |
发表时间:2004-07-21
对于两阶段提交协议,具体的根据事务处理日志恢复数据的处理不清楚,又没有那位熟悉的人出来解释一下?是不是要有数据库的支持?
|
|
返回顶楼 | |
发表时间:2004-07-21
这个问题我以前也头痛过,不过后来就不想它了,反正我从来没用到要二个数据库的情况,范不着和自已过不去。我想完全的不出差错实在太过复杂,只用那个二阶段那个是不行的。
|
|
返回顶楼 | |
发表时间:2004-08-18
两段提交事务并不是JTA特有的
只要这些资源遵从XA的规范,就可以保证事务的原子性 昏倒。。。怎么会想到需要人工去盯着事务日志文件。 难道有听说过我们需要不停的扫描数据库事务日志文件以查看事务 是否执行成功么,两段事务的实现对使用者来说是透明的。 //一家之言 |
|
返回顶楼 | |
发表时间: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实现代码。 个人理解。可能有偏差。请指正。 |
|
返回顶楼 | |