Spring 春季4&x2B;Hibernate 5.1事务在调用另一个DAO查询后自动提交

Spring 春季4&x2B;Hibernate 5.1事务在调用另一个DAO查询后自动提交,spring,hibernate,jpa,spring-transactions,atomikos,Spring,Hibernate,Jpa,Spring Transactions,Atomikos,调用另一个dao本机查询后,事务自动提交有问题 服务和dao都作为@Transactional进行了签名 我做错了什么 弹簧4.2.x Hibernate 5.1.0 Atomikos 3.9.3 这是我的设置: <tx:annotation-driven transaction-manager="transactionManager" /> <bean id="jtaPlatformAdapter" class="com.xxx.JtaPlatformAdapter">

调用另一个dao本机查询后,事务自动提交有问题

服务和dao都作为@Transactional进行了签名

我做错了什么

弹簧4.2.x

Hibernate 5.1.0

Atomikos 3.9.3

这是我的设置:

<tx:annotation-driven transaction-manager="transactionManager" />

<bean id="jtaPlatformAdapter" class="com.xxx.JtaPlatformAdapter">
    <property name="jtaTransactionManager" ref="transactionManager" />
</bean>

<bean class="com.atomikos.icatch.jta.UserTransactionManager" destroy-method="close" id="atomikosTransactionManager" init-method="init">
    <property name="forceShutdown" value="true" />
    <property name="startupTransactionService" value="true" />
</bean>

<bean class="com.atomikos.icatch.jta.UserTransactionImp" id="atomikosUserTransaction" />

<bean class="org.springframework.transaction.jta.JtaTransactionManager" id="transactionManager">
    <property name="transactionManager" ref="atomikosTransactionManager" />
    <property name="userTransaction" ref="atomikosUserTransaction" />
</bean>


<bean id="datasouce" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
    ...
</bean>

<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" id="JPAVendorAdapter">
    ...
</bean>

<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="emf" depends-on="transactionManager,jtaPlatformAdapter">
    <property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
    <property name="packagesToScan" value="com.xxx.server"/>
    <property name="dataSource" ref="datasouce" />
    <property name="persistenceUnitName" value="pun" />
    <property name="jpaVendorAdapter" ref="JPAVendorAdapter" />
    <property name="jpaPropertyMap">
        <map>
            <entry key="hibernate.connection.release_mode" value="on_close" />
            <entry key="hibernate.transaction.jta.platform" value="com.xxx.server.JtaPlatformAdapter" />
        </map>
    </property>
</bean>


谢谢

如果在代码中使用
@Transactional
,Spring将为Dao对象(包装器)创建一个代理对象

因此,如果您的应用程序正在运行,则如下所示:

public EntityObj proxyMethodForFindById(String id) {

    try {
        // 1. start transaction
        startTransaction();

        // 2. execute your code
        return yourDaoObject.findById(id);

    } finally { // [!] PSEUDO CODE: NO EXCEPTION HANDLING

        // commit transaction
        commitTransaction();
    }

}

那么代码中发生了什么

您的保存方法也被标记为
@Transactional
。因此,如果要通过设置更改对象:

model.setX(30);
model.setY(40);
Spring创建两个代理。一个用于
服务
,一个用于您的
Dao
。在
findById
-事务结束时,将提交此更改。嵌套事务是关键字


您应该在
findById
-方法中删除
@Transaction
,或者在整个Dao对象中删除更好的方法<代码>服务应该是事务性的,而不是Dao层。

请提供更多信息,更多代码:)@dit我添加了服务和Dao的代码。谢谢。好的,到底是什么问题?当dao执行本机sql查询时,事务将被提交。但我需要旧对象与新对象进行比较。在Hibernate4.2升级到5.1之前,当查询执行时,事务不会自动提交。Spring、Hibernate或Atomikos中是否存在配置错误?我的英语很基础,请不要介意。谢谢你的回答!我从方法和类中删除了@Transactional,但在执行查询之后仍然提交了事务。@T.SET yes,这是因为您得到的是相同的“触摸”对象。所以这可能不是承诺,这只是你在上面所做的改变。
@Transactional
public EntityObj findById(String id) {
    EntityObj model = null;
    String sql = "select id,x,y from EntityObj where id = :id"; // this is a native sql query

    Query query = this.entityManager.createNativeQuery(sql);
    query.setParameter("id", id);
    Object[] rs = (Object[]) query.getSingleResult();
    if (rs != null) {
      model = new EntityObj();
      model.setId(id);
      model.setX(rs[1] == null ? null : (Integer) rs[1]);
      model.setY(rs[2] == null ? null : (Integer) rs[2]);
    }

  return model;
}
public EntityObj proxyMethodForFindById(String id) {

    try {
        // 1. start transaction
        startTransaction();

        // 2. execute your code
        return yourDaoObject.findById(id);

    } finally { // [!] PSEUDO CODE: NO EXCEPTION HANDLING

        // commit transaction
        commitTransaction();
    }

}
model.setX(30);
model.setY(40);