UserTransaction


public class UserTransaction {
private static Map threadDbconnectionMap = new HashMap();
public void begin() {
dataSource.getConnection().setAutoCommit(false);
threadDbConnectionMap.put(Thread.currentThread(), dataSource.getConnection());
dataSource.getConnection().startTransaction();
}

public void commit() {
dataSource.getConnection().commitTransaction();
threadDbConnectionMap.remove(Thread.currentThread());
}
}

public class DataSource {
private static Map threadDbConnectionMap = new HashMap();
public Connection getConnection() {
if(threadDbConnectionMap.get(Thread.currentThread()) == null) {
threadDbConnectionMap.put(Thread.currentThread(), DBCONNECTION_POOL.getConnection);
}
return (Connection)threadDbConnectionMap.get( Thread.currentThread());
}
}

UserTransaction的机制就是建立一个currentThread和一个 DBconnection的map,使得在同一个thread下的所有db operation使用同一个connection,这样通过背后的同一个connection的commit或rollback来保证 transaction的atomic


public class DBConnectionPool {
// singleton Pattern
public Connection fetchConnection() ;
public void releaseConnection(Connection conn);
}

public class ThreadConnectionMap {
// singleton pattern.
private Map threadConnectionMap = new HashMap();

public Connection getConnection() {
if(threadConnectionMap.get(Thread.currentThread()) != null) {
return (Connection)threadConnectionMap.get(Thread.currentThread());
}
return DBConnectionPool.fetchConnection();
}

public Connection getConnectionInTx() {
return (Connection)threadConnectionMap.get(Thread.currentThread());
}

public void releaseConnectionInTx() {
Connection con = getConnectionInTx();
threadConnectionMap.remove(Thread.currentThread());
DBConnectionPool.releaseConnection(con);
}

public Connection newConnectionInTx() {
if(inTransaction()) {
throw new TransactionException("Transaction already started!");
}
Connection conn = DBConnectionPool.fetchConnection();
threadConnectionMap.put(Thread.currentThread(), conn);
return conn;
}

public boolean inTransaction() {
return threadConnectionMap.get(Thread.currentThread()) != null;
}

..............
}

public class VendorDataSource() implements javax.sql.DataSource {
public Connection getConnection() {
return ThreadConnectionMap.getConnection();
}

..........
}

public class VendorUserTransaction implements javax.transaction.UserTransaction {
public void begin() {
Connection con = ThreadConnectionMap.newConnectionInTx();
con.setAutoCommit(false);
}
public void commit() {
Connection con = ThreadConnectionMap.getConnectionInTx();
if(con == null) {
throw new TransactionException("cannot commit transaction, UserTransaction not started!");
}

con.commit();
ThreadConnectionMap.releaseConnectionInTx();
}
public void rollback(){
Connection con = ThreadConnectionMap.getConnectionInTx();
if(con == null) {
throw new TransactionException("cannot rollback transaction, UserTransaction not started!");
}

con.rollback();
ThreadConnectionMap.releaseConnectionInTx();
}

public boolean inTransaction() {
return ThreadConnectionMap.inTransaction();
}
....
}


以上是没有考虑XA(distributed transaction)和连接多个数据库情况的TransactionManager的实现,非常简陋,只是用于说明JTA的原理

[color=red]1。由于你只是使用了web server,没有采用application server,你的application又需要提供Transaction的control,唯一的办法是提供你自己的Transaction Manager,而不是使用UserTransaction(正如你所说的,web server不提供UserTransaction)。UserTransaction也是一种TransactionManager,由J2EE Container提供。

2。你的“dbConnection.setAutoCommit(true)”这个调用是错误的。如果你调用该语句,dbConnection就会每次execute一句sql以后自动commit了,这样你的程序中本身需要放在同一个transaction中执行的代码分散在了好几个不同的transaction中执行了,就会导致partial update的问题,data consistency就没有办法保证。

3。“死锁”的问题应该是你程序中的问题,而不应该归咎于dbConnection是否是 auto commit的。我在以前曾经写过一个自己的TransactionManager,就是通过建立一个Thread和dbConnection的map来实现的。刚开始测试这个TransactionManager的时候,也是经常出现“死锁”的问题,最后debug的结果发现并不是auto commit的问题,而是对于thread synchronization的问题处理不得当所导致的。

4。“手动地为每一个更新都编写一个恢复原始数据的方法”是错误的。试想想,如果在你手动恢复数据的过程中又出现了Exception,你又如何保证data consistency呢?

5。自己编写TransactionManager是一件比较复杂的工作,不是我想建议的。这也是为什么banq强烈推荐EJB的原因。EJB提供了TransactionManager的功能,我们可以采用EJB的解决方案,just off-the-shelf,不是吗?或者用JTA和DataSource一道实现Transaction的control。

6。如果你必须要采用自己编写的TransactionManager,我可以讲解一下J2EE CONTAINER所提供的JTA/JTS的实现原理,或许对于你编写自己的TransactionManager有一定的帮助。

7。我们知道在J2EE Spec中提供了UserTransaction和DataSource的interface的定义,具体是如何实现的留给那些J2EE Container的vendor来实现,对于application developer来说他所能见到的就是这两个interface。对于支撑这两个interface背后的东西,application developer是永远都不可能知道的。看看下面的architecture吧

User-defined Application API
----------------------------
UserTransaction DataSource
----------------------------
DBConnectionPool ThreadConnectionMap
(XAConnection, XAResource, XADataSource)

我们清楚的看到,对于UserTransaction,DataSource的支持离不开我们所看不到的J2EE spec中的一些定义,对于application developer来说,它隐藏了这些东西的复杂性。与application developer打交道的只是UserTransaction和DataSource。[/color]

http://www.jdon.com/jivejdon/thread/12894.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值