`
fengzl
  • 浏览: 215577 次
  • 性别: 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” 错误。 **2. 解决方案** - **确保 JOTM 已正确安装**。按照上文所述的步骤安装并配置 JOTM。 - **检查 ...

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

    在Java SE环境中,UserTransaction接口是用于管理事务的核心组件,主要在Java EE应用程序服务器中广泛使用,但在Java SE中也可以通过特定的方式实现。本话题将深入探讨如何在Java Standard Edition中使用...

    javax.transaction.jar

    2. **UserTransaction**:这是应用层与事务管理器交互的接口,提供了开始、回滚、提交事务的能力,以及查询当前事务的方法。 3. **TransactionManager**:用于全局事务管理,它可以控制多个资源(如数据库、消息队列...

    Tomcat中使用JOTM2.14

    <Resource name="UserTransaction" auth="Container" type="javax.transaction.UserTransaction" factory="org.objectweb.jotm.UserTransactionFactory" jotm.timeout="30"/> ``` 配置完成后,还需要在Tomcat的...

    JTA.JTS.J2SE.develop.code.rar_jts

    UserTransaction utx = (UserTransaction) new InitialContext().lookup("java:comp/UserTransaction"); utx.begin(); // 执行事务性操作 utx.commit(); ``` 这里首先通过JNDI查找UserTransaction,然后开始...

    JTA-demo说明文档.doc

    3. 提交或回滚:当所有操作完成,应用决定提交事务(`userTransaction.commit()`)或在遇到错误时回滚(`userTransaction.rollback()`)。 4. 事务管理器工作:事务管理器协调各个资源,确保它们都按照事务边界一致...

    Lab4-JTA-code_jta_choiceh76_

    例如,用户可以通过`UserTransaction.begin()`开始一个新事务,`UserTransaction.commit()`提交事务,或者`UserTransaction.rollback()`回滚事务。 2. **TransactionManager**:此接口负责事务的生命周期管理,包括...

    weblogic8上的jta编程说明(英文原版)

    utx = (UserTransaction) ic.lookup("java:comp/UserTransaction"); // 开始事务 utx.begin(); // 执行业务逻辑(此处省略) // 提交事务 utx.commit(); } catch (Exception e) { // 发生异常时回滚事务 ...

    Transaction

    - `UserTransaction` 接口的实例,用于开始、提交和回滚事务。 - 数据库连接的获取与释放,通常通过 `Connection` 对象来实现。 - `Connection` 对象的 `setAutoCommit(false)` 方法用于关闭自动提交,从而手动控制...

    EJB中的JTA与JTS例子代码

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

    相关API—Java Transaction API概述(1).rar_API_transaction api

    3. 用户事务API(UserTransaction):应用程序通过这个接口启动和结束事务,它是与业务逻辑直接交互的部分。 4. 资源管理器(Resource Manager):如数据库、消息队列等,它们实现JTA的子接口XAResource,提供事务...

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

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

    geronimo-jta_1.1_spec-1.1-sources.jar.zip

    UserTransaction utx = (UserTransaction) new InitialContext().lookup("java:comp/UserTransaction"); utx.begin(); // 执行Hibernate操作 session.getTransaction().begin(); // 数据操作 session.save...

    java实现JTA简单例子

    2. **UserTransaction接口**:这是应用程序与事务管理器交互的接口,提供了开始、提交、回滚事务的方法。在代码中,我们可能看到类似 `UserTransaction utx = ...; utx.begin();` 的代码来启动一个新的事务。 3. **...

    跨数据库的事务管理配置jta

    该类需要一个`UserTransaction`实例作为属性,因此还需要定义一个`userTransaction` Bean。在这个例子中,我们使用了Sun的默认实现,通过JNDI来获取`UserTransaction`实例。 #### 总结 通过上述配置,我们可以看到...

    michael_jta_code

    - **JNDI查找UserTransaction**:演示如何通过Java Naming and Directory Interface(JNDI)查找并使用UserTransaction实例。 - **异常处理和事务边界**:展示如何正确地处理业务异常,以及何时应该回滚事务。 - **...

    JDBC-JTA.rar_jdbc_jta_jta JDBC

    1. **UserTransaction**:定义了开始、提交、回滚事务的接口,如`userTransaction.begin()`启动事务,`userTransaction.commit()`提交事务,`userTransaction.rollback()`回滚事务。 2. **TransactionManager**:...

    WEB开发相关的Transaction管理战略

    utx = (UserTransaction) new InitialContext().lookup("java:comp/UserTransaction"); utx.begin(); // 执行业务逻辑 // ... utx.commit(); } catch (Exception e) { if (utx != null) { try { utx....

    java 事物处理的资源

    JTA包含三个主要组件:UserTransaction接口,TransactionManager接口和XAResource接口。 2. **UserTransaction**: 这个接口允许应用程序开始、提交、回滚事务,并查询当前事务状态。例如,你可以通过以下方式使用...

    Java分布式开发spring+jta+jotm

    <property name="userTransaction" ref="userTransaction"/> <bean id="userTransaction" class="org.springframework.jta.UserTransactionImpl"> ``` **分布式事务处理** 在Spring应用中,你可以使用`@...

Global site tag (gtag.js) - Google Analytics