在CMT(EJB3)中使用以下程序化事务和会话习惯用法并将Hibernate Core设置为使用CMT时,会发生什么情况?
假设需要当前的CMT事务并使用默认的@TransactionAttribute(REQUIRED)开始


休眠事务是否会加入beginTransaction()上的当前CMT?
commit()会尝试立即提交休眠事务还是等待直到当前的CMT提交?
在CMT中关闭会话时会发生什么?


B.行为是否取决于当前会话是否使用getCurrentSession()绑定到CMT?

// A: openSession()
// B: getCurrentSession();
Session session = sessionFactory.openSession();
Transaction tx = null;
try
{
    tx = session.beginTransaction();

    // do some work

    tx.commit();
}
catch (final RuntimeException e)
{
    try
    {
        tx.rollback();
    }
    catch (final RuntimeException e)
    {
        // log error
    }
    throw e;
}
finally
{
    session.close();
}


目前,在我的应用程序中,我使用的是单个数据库,并且与Hibernate一起使用程序化JDBC事务时,它可以很好地工作。现在,该应用程序还使用JMS-Queue进行邮件消息传递,并希望将其合并到全局CMT事务中。

编辑:

目前,我根本没有在应用程序中使用EntityManager,并且还希望使代码可移植到非托管环境中。

启用CMT的Hibernate配置hibernate.cfg.xml

休眠4.2.6和Glassfish 3.1.2

<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.autocommit">false</property>
<property name="hibernate.connection.datasource">jdbc/datasource</property>
<property name="hibernate.current_session_context_class">jta</property>
<property name="hibernate.transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</property>
<property name="hibernate.transaction.jta.platform">org.hibernate.service.jta.platform.internal.SunOneJtaPlatform</property>


SessionFactory检索

SessionFactory在单例EJB中构建。去除不必要的东西。

@Startup
@Singleton
public class SessionManager
{
    private SessionFactory sessionFactory;

    public SessionManager()
    {
        final Configuration configuration = new Configuration().configure();
        this.sessionFactory = configuration.buildSessionFactory();
    }
}

最佳答案

正如Luk指出的那样,这不是在CMT环境中对其进行编码的方法。无论如何,根据这里session.beginTransaction()部分是安全的
http://docs.jboss.org/hibernate/annotations/3.5/api/org/hibernate/Session.html#beginTransaction%28%29其中说


如果需要新的基础交易,请开始交易。否则,请在现有基础交易的背景下继续进行新工作


tx.rollback()也是安全的。它没有在文档中说明,但是CMTTransaction实际上执行getTransaction().setRollbackOnly(),即它只是将TX标记为回滚。提交实际上并不提交TX,但可以刷新会话。如果涉及多个资源,那么真正的提交将违反事务语义。

07-24 13:14