简介
在现代企业环境中,用多个数据库和多种品牌的数据库来存储公司数据已经不足为奇。最终,这些数据将会在不同数据库外进行比较、合并。
如果您有一个异构的数据库环境,并且计划将不同数据库中的数据收集到一个单独的应用程序中,那么您就应该可以使用传统技术执行该任务。在使用Java时,您将通过JDBC处理所有的数据库操作。清单1 展示了在Java应用程序中如何连接DB2 UDB和IDS的代码片断。
清单1. 使用JDBC建立到不同数据库的连接
1 try { // load JDBC drivers
2 Class.forName (JDBC_DRIVER_DB2);
3 Class.forName (JDBC_DRIVER_IDS);
4 }
5 catch (Exception e) {
6 // error handling
7 }
8
9 try { // establish connection and proceed with operation
10 con_db2 = DriverManager.getConnection (DBURL_DB2);
11 con_ids = Drivermanager.getConnection (DBURL_IDS);
12
13 Statement stmt_db2 = con_db2.createStatement ();
14 Statement stmt_ids = con_ids.createStatement ();
15
16 ResultSet rs_db2 = stmt_db2.executeQuery (SQL);
17 ResultSet rs_ids = stmt_ids.executeQuery (SQL);
18
19 // do something very important with the result sets...
20 }
21 catch (SQLException e) {
22 // error handling
23 }
两阶段提交协议简介
清单1中的演示允许您修改不同数据库中的数据。代替执行查询,它可以使用JDBC 方法 executeUpdate() 执行数据修改。
但是如果您需要在单个事务中封装到 DB2和IDS 表的新一行的insert,要做什么呢?
意思就是说,如果其中一条insert语句失败了,就应该将数据库(这里:两种数据库!)的初始状态恢复为客户机未执行任何动作的状态。该行为可以通过使用两阶段提交(Two-Phase-Commit)协议完成。这一标准化协议描述了如何实现分布式事务(XA)或分布式工作单元(Distributed Unit of Work,DUOW)的技术,以达到跨数据库系统的一致状态(根据 ACID)。
常规事务(单阶段提交)中,由COMMIT或ROLLBACK 所执行的事务终止是一种决定性的操作,与之相反,两阶段提交(Two-Phase-Commit)事务是分为两步(阶段)进行的。
首先,两阶段提交(Two-Phase-Commit)事务的启动与常规的单阶段提交(One-Phase-Commit)事务类似。接着,应用程序/客户机对该两阶段提交(Two-Phase-Commit)操作中所涉及的所有数据库执行其修改工作。现在,在最终提交该事务之前,客户机通知参与的数据库准备提交(第1阶段)。如果客户机从数据库收到一条“okay”,就发出命令向数据库提交该事务(第2阶段)。最后分布式事务(Distributed Transaction)结束。
两阶段提交(Two-Phase-Commit)中的第1阶段十分重要。通过首先询问数据库是否可以进行提交,一旦某一参与的数据库报告错误,就有机会立即中止整个事务。因而,第2阶段将由ROLLBACK,而非 COMMIT 完成。
图 1 提供了对于两阶段提交(Two-Phase-Commit)协议如何工作的图形化印象。正如所演示的,分布式事务(Distributed Transaction)使用由元组表示的描述符(例如:[x,b1])。其意思是,一个分布式事务(Distributed Transaction)包含两个元素。首先,有一个惟一全局事务 ID(global transaction id) —— 代表分布式事务(Distributed Transaction)的简单标识符 - 由x 表示,第二个是分支ID(branch id),它描述整个事务的一部分。一般,分支指的是一个数据库连接。如果您有一个将处理两个参与数据库的分布式事务(Distributed Transaction),您就可以用诸如 [100,1]的描述符表示一个数据库,用诸如 [100,2]的描述符表示另一数据库。因此本例中,就有一个编号为100的全局事务,其中包含两个ID 分别为1和2的分支。
“但是”,您或许会问,“如果在两阶段提交(Two-Phase-Commit)协议的第2阶段中出现错误,又将发生什么事情呢?”
“的确,您将陷入麻烦中!”
实际上,稍后我们将会讨论该主题。
图 1. 两阶段提交中的时间线和应用程序流