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的原理
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。
http://www.jdon.com/jivejdon/thread/12894.html
分享到:
相关推荐
FLEX ;Unable to access UserTransaction in DataService 解决配置问题
usertransaction-in-java-se 要测试这个问题 我看到这个链接: : 我正在阅读另一个 ,然后我进行此测试以查看结果。
javax.transaction.jar javax.transaction.jar
EJB中的JTA与JTS例子代码,JTA是一种高层的,与实现无关的,与协议无关的J2ee ... Bean自管理事务对于自管理事务的EJB,需要从EJB上下文中获取UserTransaction的接口引用,由自己负责完成事务的开始、提交或者回滚。
Java EJB JTA JTS用法示例源代码,例子对基于JTA的事务处理的实现进行了讨论,其中事务对象UserTransaction在EJB组件中执行,其实事务对象UserTransaction也可以在客户端使用。 J2EE包括了两套规范,用来支持...
#jta.UserTransaction javax.transaction.UserTransaction #jta.UserTransaction UserTransaction ## to use the second-level cache with JTA, Hibernate must be able to obtain the JTA TransactionManager #...
b) 通过查找JNDI名为javax.transaction.UserTransaction的拿到UserTransaction c) new 一个UserTransaction对象 d) 不需要实例化,直接使用接口中的方法即可 参考答案 18) 关于事务,下列说法不正确的事 a ...
<property name="userTransaction"> <!-- 数据源A --> ${jdbc.driver}"/> ${jdbc.url}"/> ${jdbc.username}"/> ${jdbc.password}"/> <!-- 数据源B --> ${jdbc2.driver}"/> ${...
在Weblogic上配置Hibernate为JNDI
JTA(Java Transaction API) 为 J2EE 平台提供了分布式事务服务。 要用 JTA 进行事务界定,应用程序要调用 javax.transaction.UserTransaction 接口中的方法。
public int delete(int sID) { DataBaseConnection dbc = null; dbc = new DataBaseConnection(); dbc.getConnection();... UserTransaction transaction = sessionContext.getUserTransaction();//获得JTA事务
jta.jar 会用到包中的usertransaction,具体什么用此处暂时不论 quartz-1.6.0.jar 会用到CronTrigger这个类,通过表达式实现精确的定时 commons-logging-1.1.1.jar 日志管理包 commons-collections-3.2.1.jar 集合...
在Tomcat6中配置好的java工程已经配置好JTOM的DataSource和UserTransaction,打包下载.请自行配置数据库与补全Tomcat6中的公共文件.然后就可以直接访问页页http://127.0.0.1:8080/DaoTemplate_my/books.jsp和...
一个开发框架 SVN 下面的地址: ...数据库采用 JDBC+DataSource&UserTransaction 的方式。如果是追求框架的人可以直接跳过。 欢迎喜欢研究技术的人评论。 详细信息 请看根目录的ReadMe.txt 文档会在今后补全。