`
fengzl
  • 浏览: 214068 次
  • 性别: Icon_minigender_1
  • 来自: 宁波
社区版块
存档分类
最新评论

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的原理

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的第一步,安装、配置、与tomcat的挂接

    FLEX ;Unable to access UserTransaction in DataService 解决配置问题

    usertransaction-in-java-se:测试这个问题http

    usertransaction-in-java-se 要测试这个问题 我看到这个链接: : 我正在阅读另一个 ,然后我进行此测试以查看结果。

    javax.transaction.jar

    javax.transaction.jar javax.transaction.jar

    EJB中的JTA与JTS例子代码

    EJB中的JTA与JTS例子代码,JTA是一种高层的,与实现无关的,与协议无关的J2ee ... Bean自管理事务对于自管理事务的EJB,需要从EJB上下文中获取UserTransaction的接口引用,由自己负责完成事务的开始、提交或者回滚。

    Java EJB JTA JTS用法示例源代码.rar

    Java EJB JTA JTS用法示例源代码,例子对基于JTA的事务处理的实现进行了讨论,其中事务对象UserTransaction在EJB组件中执行,其实事务对象UserTransaction也可以在客户端使用。  J2EE包括了两套规范,用来支持...

    hibernate.properties

    #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 #...

    J2EE面试题

    b) 通过查找JNDI名为javax.transaction.UserTransaction的拿到UserTransaction c) new 一个UserTransaction对象 d) 不需要实例化,直接使用接口中的方法即可 参考答案 18) 关于事务,下列说法不正确的事 a ...

    JTA事务源码示例

    <property name="userTransaction"> <!-- 数据源A --> ${jdbc.driver}"/> ${jdbc.url}"/> ${jdbc.username}"/> ${jdbc.password}"/> <!-- 数据源B --> ${jdbc2.driver}"/> ${...

    在Weblogic上配置Hibernate为JNDI

    在Weblogic上配置Hibernate为JNDI

    事务处理:JTA事务

    JTA(Java Transaction API) 为 J2EE 平台提供了分布式事务服务。  要用 JTA 进行事务界定,应用程序要调用 javax.transaction.UserTransaction 接口中的方法。

    事务、控制、java

    public int delete(int sID) {  DataBaseConnection dbc = null;  dbc = new DataBaseConnection();  dbc.getConnection();... UserTransaction transaction = sessionContext.getUserTransaction();//获得JTA事务

    spring 定时器

    jta.jar 会用到包中的usertransaction,具体什么用此处暂时不论 quartz-1.6.0.jar 会用到CronTrigger这个类,通过表达式实现精确的定时 commons-logging-1.1.1.jar 日志管理包 commons-collections-3.2.1.jar 集合...

    java Tomcat6 JTOM Project

    在Tomcat6中配置好的java工程已经配置好JTOM的DataSource和UserTransaction,打包下载.请自行配置数据库与补全Tomcat6中的公共文件.然后就可以直接访问页页http://127.0.0.1:8080/DaoTemplate_my/books.jsp和...

    java web 开发框架 非主流框架

    一个开发框架 SVN 下面的地址: ...数据库采用 JDBC+DataSource&UserTransaction 的方式。如果是追求框架的人可以直接跳过。 欢迎喜欢研究技术的人评论。 详细信息 请看根目录的ReadMe.txt 文档会在今后补全。

Global site tag (gtag.js) - Google Analytics