分布式事务概念与JTA编程

来源:互联网 发布:ftp自行设置端口 编辑:程序博客网 时间:2024/05/19 18:39
 

在java中有如下三种事务,

  • 简单的JDBC级的事务
  • JTA - 在EJB环境下,用户得到事务并进行控制
  • CMP - 完全由容器控制事务,用户通过Bean配置文件来定义事务行为

二三种都支持分布式事务,但只支持Java环境下的分布式事务。

下面讨论如何在Java程序里实现分布式事务,即在同一个事务里访问多个数据源。实际上就是如何使用JTA.

这里假设使用Oracle数据库,使用WebLogic部署应用,所要做的是如下几步:

1. 配置

1.1 确认数据库支持分布式事务 - oracle是支持分布式事务的,JDBC驱动也支持分布式事务

1.2 在WebLogic里配置DataSource

1.2.1. 配置连接池,注意这里应该选择驱动是Thin XA而不是Thin

1.2.2. 配置数据源,使用前面配好的XA的连接池

2. 程序实现

2.1. 实现自己的Xid

import javax.transaction.xa.*;
public class MyXid implements Xid
{
 protected int formatId;
 protected byte gtrid[];
 protected byte bqual[];
 public MyXid()
 {
 }
 public MyXid(int formatId, byte gtrid[], byte bqual[])
 {
  this.formatId = formatId;
  this.gtrid = gtrid;
  this.bqual = bqual;
 }

 public int getFormatId()
 {
  return formatId;
 }

 public byte[] getBranchQualifier()
 {
  return bqual;
 }

 public byte[] getGlobalTransactionId()
 {
  return gtrid;
 }

}
2.2. 通过JNDI找到WebLogic中配置好的数据源

public XADataSource getXADataSource()
 throws Exception
{
InitialContext ctx = new InitialContext( mgr.getProps());
XADataSource ds = (XADataSource)ctx.lookup("jdbc/xaDS");
return ds;
}
2.3. 使用XADataSource得到XAConnection,使用XAConnection得到XAResource,基于XAResource进行具体数据访问。如果我们这里lookup多个XADataSource,然后得到多个XAResource,就可以实现多数据源的事务控制。

XADataSource xaDS;
XAConnection xaCon;
XAResource xaRes;
Xid xid;
Connection con;
Statement stmt;
int ret;
xaDS = getXADataSource();
xaCon = xaDS.getXAConnection();
xaRes = xaCon.getXAResource();
con = xaCon.getConnection();
stmt = con.createStatement();
xid = new MyXid(100, new byte[]{0x01}, new byte[]{0x02});
try {
  xaRes.start(xid, XAResource.TMNOFLAGS);
  stmt.executeUpdate("insert into test_table values (100)");
  xaRes.end(xid, XAResource.TMSUCCESS);
  ret = xaRes.prepare(xid);
  if (ret == XAResource.XA_OK) {
    xaRes.commit(xid, false);
   }
}
catch (XAException e) {
 e.printStackTrace();
}
finally {
 stmt.close();
 con.close();
 xaCon.close();
}

 

JTA编程:

1. DTP Two - Phase Commit Protocol

 

在分布式事务管理领域,X/OpenDTP模型是业界最被广泛接受分布式事务管理模型。几乎所有的事务处理产品,关系数据库以及消息产品都支持该DTP模型中定义的接口。下面是对DTP模型的一段描述:

 

X/Open’s DTP model defines three components: application programs, resource managers(such as RDBMS), and a transaction manager. This model also specifies functional interfaces between application programs and the transaction manager (known as the TX interface), and between the transaction manager and the resource managers (the XA interface). With products complying to these interfaces, one can implement transactions with the two phase commit and recovery protocol to preserve atomicity of transactions.

 

DTP模型中有一个非常重要的模型,叫Two - Phase Commit Protocol。该协议作用于transaction manager和resource managers之间,保证所有的resource managers要么都commit, 要么都abort。

 

具体的TPC protocol执行过程如下:

The first phase of this protocol is the preparation phase, during which the transaction manager conducts a voting among all the resource managers registered for the target transaction. The transaction manager calls the prepare method on each resource manager, which will return a X_READONLY or XA_OK constant. The first value implies that the operations conducted on the target resource are read only, and there are no operations to be committed. The second value indicates that the resource manager is ready to commit the operations. In case the resource manager wants the transaction to be rolled back, it throws an appropriate XAException.

The second phase is a commit or recover phase. Depending on whether all resource managers are ready for a commit or not, one of these phases will be invoked by the transaction manager. In case all the resource managers return a X_OK in the first phase, the transaction manager calls the commit method on each resource manager. Please note that the two phase protocol is not fool-proof, and the commit calls may throw appropriate XAException in return. In such a case, the transaction manager should initiate the recovery phase. In case the voting determines a rollback, the transaction calls the recover on each prepared resource manager.

 

2. Java Transaction Service

 

Java 的事务实现构架遵循了DTP模型,主要有两部分组成:JTS(Java Transaction Service)JTA(Java Transaction API)

 

JTS主要规定了DTP模型中transaction manager的实现方式,而JTA则定义了application programs, transaction managerresource manager之间的接口。

 

JTA可以分为三类, 分别为针对application接口,transaction manager接口和resource manager接口。

 

application接口包括:

javax.transaction.SynchronizationAn object intended to participate in a synchronization protocol with the transaction manager should implement this interface. This mechanism is based on the Observer pattern. This interface has two methods - beforeCompletion and afterCompletion to be called before starting and after completing, respectively, the two phase commit operation.

 

transaction manager接口:

javax.transaction.Status: Defines the flags for the status of a transaction. The javax.transaction.Transaction, javax.transaction.TransactionManager, and javax.transaction.UserTransaction interfaces provide a getStatus method that returns one of the above status flags.

javax.transaction.Transaction: An object of this type is created for each global transaction. This interface provides methods for transaction completion(commit and rollback), resource enlistment (enlistResource) and delistment (delistResource), registration of synchronization objects (registerSynchronization), and query of status of the transaction (getStatus).

javax.transaction.TransactionManager: This interface is implemented by the JTS and allows an application server to communicate with the transaction manager to demarcate transactions (begin, commit, rollback, suspend and resume), set the transaction for rollback (setRollbackOnly), get the associated Transaction object (getTransaction), set the transaction timeout interval (setTransactionTimeout) and query the status of the transaction (getStatus).

javax.transaction.UserTransaction: This interface allows application components to manage transaction boundaries explicitly. This interface provides methods to begin and end transactions (begin, commit, and rollback), set the transaction for rollback (setRollbackOnly), set the transaction timeout interval (setTransactionTimeout), and get the status of the transaction (getStatus). The application server should provide an interface to create an object of this type.

javax.transaction.xa.Xid: This interface is a Java mapping of the X/Open transaction identifier xid structure. The transaction manager uses an object of this type to associate a resource manager with a transaction.

 

 

resource manager接口:

javax.transaction.xa.XAResource: This is a Java mapping of the X/Open XA interface, and is implemented by resource managers operating with the JTS. This interface provides methods to start (start) and end (end) work on behalf of a specified transaction, to prepare a transaction with the current resource (prepare), to end transactions with the current resource (commit, forget, recover, and rollback), to compare the current resource manager with another resource manager (isSameRM), and to get and set the transaction timeout (getTransactionTimeout, setTransactionTimeout).

 

 

3. 运用JTA

 

使用JTA进行分布式事务编程有两种方法,一种是通过javax.transaction.UserTransaction,另一种是通过javax.transaction.TransactionManager。但这两种方法之间的区别不是很清楚???

 

运用javax.transaction.UserTransaction(Weblogic6.1为例)

//get UserTransaction

//in websphere, jndi name is “java:comp/UserTransaction

UserTransaction  userTrans =   (UserTransaction)getInitialContext().lookup("javax.transaction.UserTransaction");

 

//begin transaction

userTrans.begin();

 

//transactional operations

 

//end transaction

userTrans.commit();

 

运用javax.transaction.TransactionManager(Weblogic6.1为例)

//get UserTransaction

UserTransaction  transManager =   (UserTransaction)getInitialContext().lookup("javax.transaction.TransactionManager");

 

//begin transaction

Transaction trans = transManager.begin();

 

//transactional operations

 

//end transaction

transManager.commit();

 

 

Transaction对象封装了事务上下文,通过该对象的enlistResource()delistResource()方法可以添加删除参与事务的resource manager, 通过registerSynchronization()方法可以注册监听对象。

 

 

http://www.javaeye.com/topic/122700

  经典话题:请教Spring的分布式事务管理: http://www.javaeye.com/post/268283?page=1
原创粉丝点击