如何在EJB中实现Transaction概念

时间:2010-09-23 10:31:07

标签: java transactions java-ee ejb

我想知道EJB中如何在内部实现事务。我想知道他们用来创建交易的逻辑。如果你能指出一些有用的文章

5 个答案:

答案 0 :(得分:8)

Hibernate不会实现事务,它依赖并包装JDBC事务或JTA事务(容器管理或应用程序管理)。

关于EJB,如果您想了解JTA事务管理器的详细信息,您需要熟练使用JTA接口UserTransactionTransactionManagerXAResourceJTA specification中描述。 JDBC API Tutorial and Reference, Third Edition对于理解JDBC驱动程序的XA部分也很有用。

然后,获取EJB容器(如JBoss)或独立JTA事务管理器(如Atomikos)的源代码来分析TM部分。祝你好运。

答案 1 :(得分:4)

这个问题可以在很多层面得到答案。

可以找到关于正在发生的事情的一般性讨论here

我的总结是这样的......首先,必须有一个事务协调器,EJB容器将知道协调器 - 通常是应用服务器的一部分。所以EJB容器所要做的就是调用

someobject.BeginTransaction()

就是这样。 EJB容器使用的实际API是JTA。 EJB实际上可以使用Bean Managed事务事务或Container托管事务。在Bean Managed案例中,实现者不得进行JTA调用。通常我们使用容器管理事务(CMT)。在这种情况下,容器具有在达到实现之前运行的逻辑。例如:

if ( we're not already in a transaction )
    begin transaction

call the EJB implementation

以后容器有逻辑

if ( finished processing request )
    commit transaction

使用其他路径在发生错误时中止事务。

现在逻辑更复杂,因为CMT EJB使用事务控制语句进行注释。例如,您可以说“如果我们已经有一个事务,请使用它”。因此,如果一个EJB调用另一个EJB,则只使用一个事务。阅读EJB规范。

然而,在任何Java EE EJB的编写中都非常明显。所以我怀疑你是在询问发生什么事情里面 JTA调用,如何实现事务管理器以及它与事务资源管理器(例如数据库)的关系。这是一个很大的话题。你实际上已经实现了XA分布式事务协议。坦率地说,我怀疑你真的需要知道这一点。在某些时候,您信任您正在使用的API。但是有一个关键细节:您的事务管理器(通常是App Server本身)必须能够告诉REsource管理器任何给定事务的命运,并且该信息必须在App Server重启后继续存在,因此一些持久的事务信息存储必须保持。您可以在某处找到事务日志,在设置App Server时,您需要确保这些日志得到很好的管理。

答案 2 :(得分:1)

来自EJB in Action本书

  

通常用于实现多种资源的协议是两阶段提交。两阶段提交协议在最终提交之前执行另外的准备步骤。 询问每个涉及的资源管理器 是否可以成功提交当前事务。如果任何资源管理器指示在尝试时无法提交事务,则放弃(回滚)整个事务。否则,允许事务继续,并要求所有资源管理器提交。

例如,资源管理器可以是数据库。其他示例包括消息服务。协调事务的组件称为事务管理器。

假设您有一个涉及两个区别数据库的应用程序 。事务管理器如何使用两阶段提交协议来执行其工作?

  1. 事务管理器询问数据库1是否可以提交当前事务
  2. 如果是,请询问数据库2是否可以提交当前事务
  3. 事务管理器要求数据库1提交
  4. 事务管理器要求数据库2提交
  5. Hibernate 构建于JDBC API之上。它只是协调一个数据库。所以,如果你打电话

    session.commit();
    

    在幕后,它会调用

    connection.commit();
    

    如果您真的想学习交易内部,我的建议是Java Transaction Processing本书。

答案 3 :(得分:0)

Hibernate有TransactionFactory

  

Transaction实例的抽象工厂。具体实现由hibernate.transaction.factory_class指定。

它有实施:JDBCTransactionFactoryJTATransactionFactoryCMTTransactionFactory。这些工厂创建了Transaction的实例 - 例如JDBCTransaction

然后我不能告诉你JTA和CMT会发生什么,但是对于JDBC来说就像将auto-commit设置为false一样简单(当你调用begin a transaction时):

connection.setAutoCommit(false);

分别在transaction.commit()connection.commit()

如果在使用会话时发生任何异常,则会调用connection.rollback()

答案 4 :(得分:0)