转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 数据库 >> SyBase >> 正文
Informix Dynamic Server 中的分布式事务         ★★★★

Informix Dynamic Server 中的分布式事务

作者:闵涛 文章来源:闵涛的学习笔记 点击数:2031 更新时间:2009/4/22 23:09:35
> 215 void execBranch (Connection con, XAResource xares, Xid xid) { 216 217 String sql = props.getProperty ("sql.statement"); 218 219 try { 220 xares.start (xid, javax.transaction.xa.XAResource.TMNOFLAGS); 221 222 Statement stmt = con.createStatement (); 223 stmt.executeUpdate (sql); 224 225 xares.end (xid, javax.transaction.xa.XAResource.TMSUCCESS); 226 } 227 catch (XAException e) { 228 System.err.println ("XA exception caught:"); 229 System.err.println ("Cause : " + e.getCause ()); 230 System.err.println ("Message: " + e.getMessage ()); 231 e.printStackTrace (); 232 } 233 catch (SQLException e) { 234 sqlerr (e); 235 } 236 }

第 219-226 行代码包含了分布式事务(Distributed Transaction)中为相应分支所使用的真正 SQL 语句。分支边界在第 220 行中以 start 方法开始。传递给该方法的参数就是我们已经知道的事务 ID,而第二个参数包含了用于该 XA 事务的一些附加信息。因为这是第一个两阶段提交(Two-Phase-Commit)协议操作,所以不需要向该方法传递任何特殊信息。TMNOFLAGS 说明了这一事实。分支边界终止于第 225 行。标志 TMSUCCESS 描述所有操作都成功。

在 IDS 和 DB2 的分支都执行之后,全局事务就准备提交这些修改。当然,在可以向数据库传送最后的提交之前,必须询问数据库是否准备进行提交。


            104         if (prepareCommit (db2xares, db2xid) == XAResource.XA_OK &&
            105             prepareCommit (ifxxares, ifxxid) == XAResource.XA_OK) {
            106             // both branches are ready to commit
            107             commitBranch (db2xares, db2xid);
            108             commitBranch (ifxxares, ifxxid);
            109         }
            110         else {
            111             // a resource reported an error
            112             rollbackBranch (db2xares, db2xid);
            113             rollbackBranch (ifxxares, ifxxid);
            114         }
            116     } // end of constructor
            

第 104 和 105 行通知数据库准备提交。如果数据库报告 XAResource.XA_OK,就可以提交整个事务。否则,该事务就将被 ROLLBACK 中止。


            417     int prepareCommit (XAResource xares, Xid xid) {
            418
            419         int rc = 0;
            420
            421         System.out.print ("Prepare XA branch (" +
            422             Byte.toString ((xid.getGlobalTransactionId ())[0]) + ", " +
            423             Byte.toString ((xid.getBranchQualifier ())[0]) + "): ");
            424
            425         try {
            426             xares.prepare (xid);
            427         }
            428         catch (XAException e) {
            429             xaerr (e);
            430         }
            431
            432         System.out.println ("Okay.");
            433         return rc;
            434     }
            

prepareCommit() 方法中最重要的一行在第 426 行中。prepare 方法引起数据库调用两阶段提交协议(Two-Phase-Commit)的“第 1 阶段”。

根据“第 1 阶段”的结果,将提交或中止该分布式事务(Distributed Transaction)。下面是将用于发出这些必要操作的两个方法。


            128     void commitBranch (XAResource xares, Xid xid) {
            129
            130         System.out.print ("Commit XA branch (" +
            131             Byte.toString ((xid.getGlobalTransactionId ())[0]) + ", " +
            132             Byte.toString ((xid.getBranchQualifier ())[0]) + "): ");
            133
            134         try {
            135             // second parameter is 'false' since we have a two phase commit
            136             xares.commit (xid, false);
            137         }
            138         catch (XAException e) {
            139             xaerr (e);
            140         }
            141
            142         System.out.println ("Okay.");
            143     }
            

如果“第 1 阶段”未报告任何错误,就在第 136 行中为 xid 所描述的事务分支提交“第 2 阶段”。方法 commit() 中的第二个参数区分单阶段或两阶段提交操作。因为我们具有一个两阶段提交操作,所以必须将该值设置为 false

下面的例子展示了如何为数据库回滚事务分支。


            446     void rollbackBranch (XAResource xares, Xid xid) {
            447
            448         System.out.print ("Rollback XA branch (" +
            449             Byte.toString ((xid.getGlobalTransactionId ())[0]) + ", " +
            450             Byte.toString ((xid.getBranchQualifier ())[0]) + "): ");
            451
            452         try {
            453             xares.rollback (xid);
            454         }
            455         catch (XAException e) {
            456             xaerr (e);
            457         }
            458
            459         System.out.println ("Okay.");
            460     }
            

问题解答
本文中的例子演示了如何在 Java 中使用 JTA 实现两阶段提交(Two-Phase-Commit)协议。在该应用程序中,如果一个事务分支报告了错误,您就要负责进行错误处理。但是“两阶段提交协议简介”小节中提到仍然存在一个问题,那就是如果第 2 阶段中一个事务分支发生故障,该怎么办呢?

如果再次查看程序代码,您可以看到在“第 1 阶段”和“第 2 阶段”之间有一个很小的时间间隔。在这一时间间隔中,出于某种理由,其中某一参与数据库可能崩溃。如果发生了,我们将陷入分布式事务已经部分提交的情形中。

假定下列情形:在“第 1 阶段”之后,您从 DB2 和 IDS 数据库中都收到了“okay”。在下一步中,应用程序成功提交了 DB2 的事务分支。接着,应用程序通知 DB2 事务分支提交事务。现在,在应用程序可以通知 IDS 事务分支提交它这一部分之前,IDS 引擎由于断电发生崩溃。这就是一种部分提交全局事务的情形。您现在该怎么办呢?

在重启之后,DB2 和 IDS 都将尝试恢复打开的事务分支。该引擎等待来自应用程序的提示如何做。如果应用程序没有准备重新发送“第 2 阶段”的提交,该事务分支将被引擎所启动的试探性回滚中止。这是非常糟糕的,因为这将使该全局事务处于不一致状态。

一种解决方案是用一个小型应用程序连接引擎中打开的事务分支,并通知引擎提交或回滚这一打开的事务。如果您使用 IDS 作为后端,那么还有一个隐藏的 onmode 标志,允许您结束打开的事务分支。(onmode -Z xid)。

在 DB2 UDB 中,您可以发出 LIST INDOUBT TRANSACTIONS 来获得打开的 XA 事务的有关信息。您必须查看 DB2 Information Center 中的描述来解决该问题。

上面描述的情形是一个很好的例子,也是使用应用程序服务器(Application Server)或事务监控器(Transaction Monitor)的理由。在使用一个中间层服务器时,就由该服务器负责保持事情正常。

备选方案
清单 1 演示了在应用程序中从数据库读取数据并处理结果的可行方法。如果您的应用程序是“只读”应用程序,IBM® 就提供了另一种解决方案,称作 WebSphere® Information Integrator。WebSphere Information Integrator 使用来自 DB2 UDB(或 DB2 Data Joiner、DB2 Relational Connect)的联邦数据库技术,以将多个数据库(通常:数据源)虚拟化(virtualize)到一个数据库中。不同的、非本地的数据库中的表都链接到 DB2 UDB 中。该操作对于客户机应用程序是完全透明的。客户机可以访问其他数据库中的所有远程表,就像它们是本地 DB2 UDB 表一样。正如 清单 1 中引用的,不再需要连接两个数据库。到 DB2 UDB 的单个连接就已经足够了,因为 DB2 中可以看到 IDS 数据库中的所有表。

目前,WebSphere Information Integrator 不支持两阶段提交,然而,将来的版本将支持两阶段提交协议;这将带来实现企业应用程序的新方法

 

上一页  [1] [2] [3] 


[聊天工具]企业邮件系统的利器----FoxMail Server  [系统软件]OPEN SERVER 5.0.5安装EXP300阵列柜
[系统软件]关于Windows2000Server的灾难恢复  [常用软件][网络]下载服务革命性风暴Poco Server评测
[C语言系列]动态创建SQL Server数据库、表、存储过程等架构信…  [C语言系列]SQL Server到DB2连接服务器的实现
[C语言系列]SQL Server到SYBASE连接服务器的实现  [C语言系列]SQL Server到SQLBASE连接服务器的实现
[C语言系列]SQL Server连接VFP数据库的实现  [C语言系列]ASP+SQL Server之图象数据处理
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · Sql Server  · MySql
    · Access  · ORACLE
    · SyBase  · 其他
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台