2017-01-17 14 views
0

У меня возникла проблема на некоторое время и я не могу понять, что я делаю неправильно. Вот контекст:(Сделки не откатываются назад) Данные Spring, JTA, JPA, Wildfly10

  • Spring 4.3.4.RELEASE
  • весна-данных JPA 1.10.6.RELEASE
  • Hibernate 5.2.5.Final
  • Я использую wildfly 10, начиная с с помощью Maven плагин
  • сконфигурирован для источника данных JNDI поиска правильно
  • с помощью пружинных-данных с помощью @Repository интерфейсов
  • создано EntityManagerFactory как весенний боба (LocalContainerEntityMa nagerFactoryBean)
  • , как для менеджера транзакций, я пытался использовать оба 'TX: JTA-транзакция менеджера' и весну фасоль (JtaTransactionManager)
  • сконфигурировано persistence.xml
  • включить 'TX: аннотации привода'

Итак, я получил @Service класс (SistemaBOImpl), который имеет @Repository впрыскивается (SistemaDAO) и метод испытаний для транзакционного поведения:

@Service 
@Transactional(propagation = Propagation.SUPPORTS) 
public class SistemaBOImpl extends AbstractBO<Sistema, Long> implements SistemaBO { 

    @Autowired 
    public SistemaBOImpl(SistemaDAO sistemaDAO) { 
     super(sistemaDAO); 
    } 

    @Override 
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = { BusinessException.class }) 
    public void testTrans() throws BusinessException { 
     try { 
      final Sistema s = findOne(1L); 
      s.setCodUsuAlt(SimpleDateFormat.getInstance().format(new Date())); 
      s.setDatAlt(new Date()); 
      save(s); //1st save 

      save(new Sistema()); //2nd save 
     } catch (Exception e) { 
      throw new RuntimeException(e); 
      // throw new BusinessException(e); 
     } 
    } 
} 

DAO

@Repository 
@Transactional 
public interface SistemaDAO extends DAO<Sistema, Long>, JpaRepository<Sistema, Long> {} 

Проблема заключается в том: Хотя второй сохранить не будет завершена из-за ограничений базы данных (и я сделал это нарочно, 1st спасбросок поручены и данные изменяются. Я не могу понять, почему он не откатывает все. Что я делаю неправильно?!?

Вот мой другой конфигурационный файл:

applicationContext.xml

<beans ... ommited namespace hell> 
<context:annotation-config /> 

<context:component-scan base-package="br.com.myco" /> 

<tx:jta-transaction-manager /> 

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

<jpa:repositories base-package="br.com.myco" /> 

<jee:jndi-lookup id="dataSource" jndi-name="java:jboss/datasources/Myco_DB" /> 

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="jtaDataSource" ref="dataSource" /> 
    <property name="jpaVendorAdapter" > 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" > 
      <property name="database" value="MYSQL" /> 
      <property name="showSql" value="true" /> 
     </bean> 
    </property> 
    <property name="persistenceUnitName" value="tof"/> 
    <property name="packagesToScan" value="br.com.myco.tof"/> 
</bean> 

persistence.xml

<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd" version="2.1"> 
<persistence-unit name="myco" transaction-type="JTA"> 
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> 
    <jta-data-source>java:jboss/datasources/Myco_DB</jta-data-source> 
    <class>br.com.abril.tof.domain.Sistema</class> 
    <exclude-unlisted-classes>false</exclude-unlisted-classes> 
    <properties> 
     <property name="hibernate.show_sql" value="false" /> 
     <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" /> 
     <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform"/> 
     <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup" /> 
    </properties> 
</persistence-unit> 

web.xml

<web-app version="3.1" ...> 

<display-name>MyCO</display-name> 
<description>MyCO</description> 

<!-- Carrega Spring --> 
<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 

<servlet> 
    <servlet-name>myco</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <load-on-startup>1</load-on-startup> 
</servlet> 

<servlet-mapping> 
    <servlet-name>myco</servlet-name> 
    <url-pattern>/</url-pattern> 
</servlet-mapping> 

<persistence-unit-ref> 
    <persistence-unit-ref-name>jpa/EntityManager</persistence-unit-ref-name> 
    <persistence-unit-name>myco</persistence-unit-name> 
</persistence-unit-ref> 

<session-config> 
    <session-timeout>60</session-timeout> 
</session-config> 
</web-app> 

Log/StackTrace для 2 сохранить

Caused by: org.hibernate.HibernateException: Could not apply work 
at org.hibernate.resource.transaction.backend.jta.internal.JtaIsolationDelegate.doTheWorkInNewTransaction(JtaIsolationDelegate.java:112) 
at org.hibernate.resource.transaction.backend.jta.internal.JtaIsolationDelegate.delegateWork(JtaIsolationDelegate.java:65) 
at org.hibernate.id.enhanced.TableStructure$1.getNextValue(TableStructure.java:125) 
at org.hibernate.id.enhanced.NoopOptimizer.generate(NoopOptimizer.java:40) 
at org.hibernate.id.enhanced.SequenceStyleGenerator.generate(SequenceStyleGenerator.java:412) 
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:101) 
at org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:67) 
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:189) 
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:132) 
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:58) 
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:775) 
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:748) 
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:753) 
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1146) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:497) 
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:347) 
at com.sun.proxy.$Proxy63.persist(Unknown Source) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:497) 
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:298) 
at com.sun.proxy.$Proxy63.persist(Unknown Source) 
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:506) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:497) 
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:503) 
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:488) 
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:460) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) 
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282) 
**at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)** 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) 
... 65 more 
+0

У вас есть 'rollbackFor = BusinessException.class', но в случае ошибки выбрасывается' RuntimeException'. Автоматический откат будет выполняться только в том случае, если метод выбрасывает «BusinessException», чего нет, поэтому откат не выполняется (как и ожидалось). – manish

+0

Привет, я знаю, это было всего лишь одним из многих тестов, которые я сделал. Я пробовал: ommiting конфигурации «rollbackFor» и бросить оба исключения, я попытался поместить Runtime и BusinessException в этот конфиг и так далее ... – RaphaelCosta

+0

Можете ли вы отладить ваше приложение, чтобы проверить, действительно ли запущены транзакции для теста? Вы можете установить контрольные точки в «TransactionInterceptor», чтобы проверить это. Перехватчик перехватывает вызовы для прокси, сгенерированного для управляемого компонентом Spring. С вашей конфигурацией Spring (в частности, '') прокси будет экземпляром 'SistemaBO' (поскольку прокси-серверы по умолчанию - это прокси-серверы JDK, прокси-интерфейсы которых не являются классами). Таким образом, если 'SistemaBO' не объявляет метод' testTrans' с '@ Transactional', может быть, транзакция не выполняется при запуске теста. – manish

ответ

0

Получил это!

После отладки, например, многого и поиска недостатков в конфигурациях транзакций, я понял, что весь мой бизнес не был прокси. Ну, это говорит, что я думал, что это должна быть весна, конфигурирующая мои бобы, и, ради бога :), было. я получил весной-MVC конфигурации сделано неправильно (WEB-INF/мико-servlet.xml):

<context:component-scan base-package="br.com.myco" /> 
<mvc:annotation-driven /> 

См бейс-пакет? Он указывал на те же пакеты, как в моем applicationContext.xml:

<context:component-scan base-package="br.com.myco" /> 

Я просто должен был изменить этот конфиг в мико- servlet.xml к основному Mvc пакета:

<context:component-scan base-package="br.com.myco.service" /> 

И работал только отлично!

Kudos для этого question on stackoverflow также для ознакомления о проблеме.

0

Проверьте, если двигатель MySQL вы используете InnoDB. Если вы используете MyISAM, транзакция не поддерживается.

+0

Привет, Квинси, я использую InnoDB. – RaphaelCosta

+0

Итак, вы используете поддержку транзакций? – Quincy

+0

Ну, поскольку я использую транзакцию InnoDB .... Кроме того, я заверил, что для autocommit MySQL установлено значение FALSE. – RaphaelCosta