在Glassfish中刷新后,将提交EJB事务

时间:2016-08-30 14:54:12

标签: hibernate jpa glassfish multi-tenant c3p0

编辑:当我打开Glassfish的事务记录时:

CLASSNAME: com.sun.enterprise.transaction.JavaEETransactionImpl --Created new JavaEETransactionImpl, txId = 21 
Hibernate: update ... 
Hibernate: delete ... 
CLASSNAME: com.sun.enterprise.transaction.JavaEETransactionImpl  --In JavaEETransactionImpl.commit, jtsTx=null nonXAResource=null
运行两个sql语句后,

JavaEETransactionImpl正确提交。

我还在交易期间(更新后和删除前)检查了C3P0连接的实例,Connection.getAutoCommit()返回true这是什么原因,为什么调用getEntityManager().flush()时会提交sql语句。

AFAIK Connection在交易过程中不应处于autoCommit模式,Hibernate有责任将其关闭。当我关闭autoCommit时,在MultiTenantConnectionProvider中创建Connection实例时,永远不会提交更改。

所以问题是, Hibernate没有关闭连接的autoCommit,也没有在事务发生后调用connection.commit()(提交仅执行,因为默认的autoCommit设置为在C3P0中为真)。的为什么吗

进行以下设置:

Glassfish 4.0,Hibernate 5.0.7使用数据库方法为multi-tenancy设置,通过MultiTenantConnectionProvider实现和MS SQL Server 2014为Hibernate提供C3P0连接,

容器管理 bean中的

事务无效。

例如,我在无状态会话bean中有一个删除实体的业务方法:

@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void remove(IPersistentObject entity, IUser user) {
    entity.setModifiedBy(user.getIdentification());
    entity.setModifiedDate(ZonedDateTime.now());
    entity.setStatus(DataRecordStatus.DELETED);

    IPersistentObject merge = getEntityManager().merge(entity);
    getEntityManager().flush();

    getEntityManager().remove(merge);
    getEntityManager().flush();

}

在第一步中,此方法设置有关执行删除的人员和时间的实体元数据。之后,调用flush()以触发数据库更新触发器,从而将更改保存到历史记录表中。之后,实体将从实时(非历史)表中删除。

问题,这不是在一个事务中执行的。当我调试代码时,在第一次刷新之后,我可以看到数据库中的DELETED状态,尽管事务应该仍在运行并且只在EJB方法结束后提交。

当我为一个实体执行此方法时,由于它在另一个表中被引用而无法删除,因此会抛出ConstraintViolationException,但元数据更改不会回滚,并且实体仍处于损坏状态(DELETED)状态)。

的persistence.xml:

<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="sqlServerTestPU" transaction-type="JTA">
    <!-- 1 -->
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <!-- 2 -->
    <!-- We are multi tenant, do not specify JTA data source     
    <jta-data-source>${db.jdbcName}</jta-data-source> -->
    <!-- 3 -->
    <properties>
      <property name="hibernate.archive.autodetection" value="class"/>
      <property name="hibernate.dialect" value="org.hibernate.dialect.SQLServer2008Dialect"/>
      <property name="hibernate.show_sql" value="${hibernate.showSql}"/>
      <property name="hibernate.format_sql" value="${hibernate.showSql}"/>
      <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.SunONETransactionManagerLookup"/>
      <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform"/>
      <property name="hibernate.enable_lazy_load_no_trans" value="true"/>
      <property name="hibernate.multiTenancy" value="DATABASE"/>
      <property name="hibernate.multi_tenant_connection_provider" value="at.ts.wh.dal.WHMultiTenantConnectionProvider"/>
      <property name="hibernate.tenant_identifier_resolver" value="at.ts.wh.dal.WHCurrentTenantIdentifierResolver"/>
    </properties>
  </persistence-unit>
</persistence>

当我从MultiTenantConnectionProvider记录检索/释放连接时,我得到类似这样的内容:

TENANT1 getConnection com.mchange.v2.c3p0.impl.NewProxyConnection@73b9aad9]]
Hibernate: update ...
Hibernate: delete ...
TENANT1 releaseConnection com.mchange.v2.c3p0.impl.NewProxyConnection@73b9aad9]]

看起来连接是为整个业务方法(事务)保留的,这是正常的,但提交是通过刷新进行的。

如何使交易有效?谢谢你的帮助!

0 个答案:

没有答案