Spring 春季4&x2B;Hibernate 5.1事务在调用另一个DAO查询后自动提交
调用另一个dao本机查询后,事务自动提交有问题 服务和dao都作为@Transactional进行了签名 我做错了什么 弹簧4.2.x Hibernate 5.1.0 Atomikos 3.9.3 这是我的设置: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">
<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);