2015-02-23 4 views
4

Я использую нативный метод менеджера сущностей, и я хочу, чтобы откатить, когда какая-то ошибка occurs.For это я попытался @Transactional аннотации, но это не rollback.Below моего примера кодкак откатить в EntityManager createNativeMethod

контроллера

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

Это так, как я сделал, но это не откат, так скажите мне, как сделать

EDIT

Я попытался USIN г

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

@Transactional(rollbackFor=MyException.class)) 

Во всех 3-х случаях, это не откатить

Update

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

Если требуется больше информации, пожалуйста, спросите

+0

Я просто ответил на очень похожий вопрос [сегодня] (http://stackoverflow.com/questions/28696152/spring-transactional-not-starting-a-transaction/28704004#28704004), это может быть той же проблемой. В основном вы используете управляемый аннотацией режим = «aspectj», но я не вижу «load-time-weaver» в любом месте вашего контекста. – ikumen

+0

@ user2264997 Если я создаю '' to '', то мое приложение не запускается. Я имею в виду, когда я прямо на проекте и выберите запуск на сервере, затем он не запустится. Подождите, я отправлю сообщение об ошибке – SpringLearner

+0

@ user2264997, пожалуйста, просмотрите эту [ошибку] ​​(http://pastie.org/9980637) – SpringLearner

ответ

1

Проблема заключается в том, что весной не вводится EntityManager. Экземпляр EntityManager создается вашей полезной группой entityManagerUtil.entityManager(). Это означает, что каждый раз, когда вы используете новый EntityManager, они не являются частью транзакции метода.

Чтобы решить эту проблему: пусть Spring правильно вставляет EntityManager (попробуйте, например, ввести его прямо в ваш исходный компонент с помощью @PersistenceContext и выполнить эти три метода непосредственно в одном и том же методе).


ОБНОВЛЕНИЕ: Проблема заключался в том, что код, который бросил исключение был в попытке/поймать блок, таким образом, транзакция не была развернута-обратно весной. Транзакция откатывается только тогда, когда транзакционный метод завершается с RuntimeException (по умолчанию).

0

Вы должны изменить способ, чтобы иметь rollbackFor свойство для @Transactional аннотацию, так что

@Transactional(rollbackFor=MyException.class) 
public String saveinfo(Long id) 

Имейте в виду, что MyException должен быть снят исключением, так как проверяются исключения выброшен из @Transactional метода не приведет к транзакции откат.

Update:

Чтобы убедиться, что все правильно

  1. Убедитесь, что Spring действительно создает прокси и ваш метод выполняется в транзакции (например, использование TransactionSynchronizationManager.isActualTransactionActive())

  2. Проверить что MyException.class действительно исключено исключение (подкласс java.lang.RuntimeException или java.lang.Error)

  3. Убедитесь, что ваше исключение действительно выбрано (например,не обнаружены как-то)

И почему ваш контроллер saveInfo() отмечен как транзакционный? Это не рекомендуется, только сервисный уровень должен быть отмечен как транзакционный. См. Например, сообщение this.

+0

Спасибо за ответ, я попробовал это до того, как он не откат. Этот откат происходит только в HQl, но не для собственных запросов. – SpringLearner

+0

Не могли бы вы обновить свой вопрос с помощью кода, который вы пробовали? (Я обновил свой ответ с некоторой информацией) – vtor

+0

Я изменил вопрос – SpringLearner

0

Возможно, entityManagerUtil (который вы используете в своей реализации DAO) использует или создает диспетчер сущностей, который не работает в окружающем контексте транзакции. Пожалуйста, обратите внимание на следующее: tutorial Здесь JPA EntityManager впрыскивается с @PersistenceContext

+0

Эй, это то, что я уже объяснил. –

+0

Извините, не видел - вы были на 2 мин быстрее. – gclaussn

+0

Так я использую entittymanager http://pastie.org/9980724 – SpringLearner

0

Вы можете убедиться, что ваш persistenceUnit настроил следующее, transaction type (по желанию) и hibernate.connection.autocommit к false, если не пожалуйста, сделайте это.

<persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL"> 
     <properties> 
      <property name="hibernate.connection.autocommit" value="false" /> 
     </properties> 
    </persistence-unit> 

Я исключила другие свойства для краткости

+0

Я использую JPA не спящий режим – SpringLearner

+0

Какая реализация JPA? – iamiddy

+0

spring JPA реализация – SpringLearner

0

@SpringLearner получить менеджер Entity контекстного сохранения слоя на аннотации он будет заботиться рулоном назад @PersistenceContext, реализуемый образец с сценарием, как указано в вашем вопросе, проверенный откат, он работает нормально, и я не использовал собственный запрос, его простой пример, который вы можете изменить, и test.it должен работать.

blog with git hub link and full source code

Смежные вопросы