如何回滚entitymanager createNativeMethod


问题内容

我正在使用实体管理器的本机方法,并且希望在发生某些错误时回滚。为此,我尝试了@Transactional批注,但没有回滚。以下是我的示例代码

控制者

@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()

这是我的方法,但没有回滚,所以请告诉我该怎么做

编辑

我尝试使用

@Transactional(rollbackFor=MyException.class,propagation = Propagation.REQUIRED) and  @Transactional(propagation = Propagation.REQUIRED) and

@Transactional(rollbackFor=MyException.class))

在这3种情况下,都没有回滚

更新资料

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);
}

如果需要更多信息,请询问


问题答案:

问题似乎EntityManager是Spring没有注入。该EntityManager实例由您的实用程序类创建entityManagerUtil.entityManager()。这意味着,每次使用new时EntityManager,它们都不是方法事务的一部分。

为了解决这个问题:让Spring正确注入EntityManager(例如,尝试使用来将其直接注入原始Bean中,@PersistenceContext并在同一单个方法中直接进行这三种方法)。


更新:问题是引发异常的代码在try /
catch块中,这样,Spring不会回滚事务。仅当事务方法以RuntimeException(默认)退出时,事务才会回滚。