问题描述
我正在使用实体管理器的本机方法,想在发生某些错误时回滚.为此,我尝试了@Transactional
批注,但没有回滚.下面是我的示例代码
I am using native method of entity manager and I want to rollback when some error occurs.For this I tried @Transactional
annotation but this does not rollback.Below is my sample code
控制器
@Autowired
ServiceImpl ServiceImpl;
@RequestMapping("/saveinfo")
@ResponseBody
@Transactional
public String saveinfo(Long id)
{
ServiceImpl.saveInfo(id);
}
服务等级
@Autowired
DAOImpl daoImpl;
@Transactional
public String saveinfo(Long id)
{
daoImpl.saveInfo1(id);
daoImpl.saveInfo12(id);
daoImpl.saveInfo12(id);
}
DAO类
@Override
public BigInteger saveInfo11() {
Query query = entityManagerUtil.entityManager().createNativeQuery("insert query");
return (BigInteger)query.getSingleResult();
}
@Override
public BigInteger saveInfo12() {
Query query = entityManagerUtil.entityManager().createNativeQuery("insert query");
return (BigInteger)query.getSingleResult();
}
@Override
public BigInteger saveInfo13() {
Query query = entityManagerUtil.entityManager().createNativeQuery("insert query");
return (BigInteger)query.getSingleResult();
}
现在在上面的代码中,
如果我在saveInfo3()
中遇到一些运行时错误,那么我想回滚以下方法saveInfo1()
和saveInfo2()
If I have some runtime error in saveInfo3()
then I want to rollback methods of saveInfo1()
and saveInfo2()
这是我的方法,但是没有回滚,所以请告诉我该怎么做
This is the way I did but it did not rollback,so Please tell me how to do
编辑
我尝试使用
@Transactional(rollbackFor=MyException.class,propagation = Propagation.REQUIRED) and @Transactional(propagation = Propagation.REQUIRED) and
@Transactional(rollbackFor=MyException.class))
在所有3种情况下,它都没有回滚
In all the 3 cases ,it did not rollback
更新
applicationcontext.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/data/mongo
http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd">
<!--<context:annotation-config />-->
<context:spring-configured/>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
<property name="dataSource" ref="dataSource"/>
<property name="persistenceUnitName" value="persistenceUnit"/>
</bean>
<bean id="messageDigestPasswordEncoder" class="org.springframework.security.authentication.encoding.MessageDigestPasswordEncoder">
<constructor-arg value="SHA-256" />
</bean>
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
<property name="driverClassName" value="${database.driverClassName}"/>
<property name="url" value="${database.url}"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
</bean>
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
<context:property-placeholder location="classpath*:META-INF/database.properties"/>
<context:property-placeholder location="classpath*:META-INF/project.properties"/>
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean id="propertiesUtil" class="com.work.project.utils.PropertiesUtil">
<property name="locations" >
<list>
<value>classpath*:META-INF/*.properties</value>
</list>
</property>
</bean>
<context:component-scan base-package="com.work.project">
<context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>
<task:executor id="myexecutor" pool-size="5" />
<task:annotation-driven executor="myexecutor"/>
</beans>
修改后的控制器方法
@Autowired
ServiceImpl ServiceImpl;
@RequestMapping("/saveinfo")
@ResponseBody
//Now I dont use transactional annotation in controller class
public String saveinfo(Long id)
{
ServiceImpl.saveInfo(id);
}
如果需要更多信息,请询问
If any more information is required please ask
推荐答案
问题似乎是EntityManager
不是由Spring注入的. EntityManager
实例是由实用程序类entityManagerUtil.entityManager()
创建的.这意味着,每次使用新的EntityManager
时,它们都不属于方法事务.
The problem seems to be that the EntityManager
is not injected by Spring. The EntityManager
instance is created by your utility class entityManagerUtil.entityManager()
. This means, that everytime when you use a new EntityManager
, they are not part of your method transaction.
为了解决这个问题:让Spring正确地注入EntityManager
(例如,尝试使用@PersistenceContext
将其直接注入原始bean中,并在同一单个方法中直接进行这三种方法).
In order to solve this problem: let Spring inject correctly the EntityManager
(try for example injecting it directly in your original bean with @PersistenceContext
and do those three methods directly in the same single method).
更新:问题是引发异常的代码在try/catch块中,这样,Spring不会回滚事务.仅当事务方法以RuntimeException
(默认)退出时,事务才会回滚.
UPDATE:The problem was that the code that threw the exception was in a try/catch block, this way, the transaction was not rolled-back by Spring. Transaction is rolled-back only when the transactional method exits with an RuntimeException
(by default).
这篇关于如何回滚entitymanager createNativeMethod的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!