2015-04-13 3 views
2

У меня есть метод в классе хранилища, помеченный как @Transactional, то аспект выполняется, как показано в StackTrace, но исключение бросают это «сделка требуется исключение»сделки требуется исключение JPA/Spring

Я изменил @Repository аннотация для @Component (и, похоже, это исправляло эту проблему в некоторых ситуациях), но она все еще происходит на веб-роли.

Вот StackTrace:

2015-04-13 08:00:56,497 [http-nio-8080-exec-9] WARN es.mycompany.util.filters.MyFilter - Error storing : /admin/online/update 
org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query 
     at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:410) 
     at org.springframework.orm.jpa.aspectj.JpaExceptionTranslatorAspect.ajc$afterThrowing$org_springframework_orm_jpa_aspectj_JpaExceptionTranslatorAspect$1$18a1ac9(JpaExceptionTranslatorAspect.aj:37) 
     at es.mycopmany.dao.MyDAO.updateLastUpdatedTs_aroundBody2(MyDAO.java:36) 
     at es.mycopmany.dao.MyDAO$AjcClosure3.run(MyDAO.java:1) 
     at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96cproceed(AbstractTransactionAspect.aj:66) 
     at org.springframework.transaction.aspectj.AbstractTransactionAspect$AbstractTransactionAspect$1.proceedWithInvocation(AbstractTransactionAspect.aj:72) 
     at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281) 
     at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96c(AbstractTransactionAspect.aj:70) 
     at es.mycompany.dao.MyDAO.updateLastUpdatedTs(MyDAO.java:31) 

А вот код бросает исключение:

@Transactional 
    public void updateLastUpdatedTs(String id, Calendar date) { 
     Query query = entityManager.createQuery("update MyEntity set lastUpdatedTs = :ts " 
       + " where id= :id"); 
     query.setParameter("ts", date); 
     query.setParameter("id", id); 
     query.executeUpdate(); 
    } 

транзакционных аннотаций происходит от org.springframework.transaction.annotation.Transactional

Версии :

Spring: 4.1.5.RELEASE 
Hibernate: 4.3.8.Final 
Aspectj: 1.8.5 
Tomcat 8.0.20 

Конфигурации:

EMF:

<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" 
     id="entityManagerFactory"> 
     <property name="persistenceUnitName" value="athena" /> 
     <property name="dataSource" ref="dataSource" /> 
     <property name="jpaDialect"> 
      <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/> 
     </property> 
    </bean> 

Сделки:

<bean class="org.springframework.orm.jpa.JpaTransactionManager" 
     id="transactionManager"> 
     <property name="entityManagerFactory" ref="entityManagerFactory" /> 
    </bean> 

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

Я буду по-настоящему гайки с этим, любая помощь будет большим.

Как примечание, все это работает прекрасно на моей среде разработки (Windows, идея Tomcat 8, JDK 8.0.31 (Oracle), но он поднимает эту ошибку на Amazon EC2 Elasticbeanstalk (Tomcat 8, 64-битной Amazon Linux 2015,03, Open JDK 8.0.31 (Пробовал использовать 8.0.40 от Oracle, а)

Edit: немного подробнее: исключение брошено на фильтр, в конце всей цепочки фильтров

Ниже приведена информация об отладке до исключения:

2015-04-13 14:57:48,578 [http-bio-8080-exec-7] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Creating new transaction with name [MyService.myMethod]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '' 
2015-04-13 14:57:48,578 [http-bio-8080-exec-7] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Opened new EntityManager [[email protected]] for JPA transaction 
2015-04-13 14:57:48,580 [http-bio-8080-exec-7] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Exposing JPA transaction as JDBC transaction [org.springframewo[email protected]3112368a] 
2015-04-13 14:57:48,581 [http-bio-8080-exec-7] TRACE org.springframework.transaction.support.TransactionSynchronizationManager - Bound value [[email protected]] for key [HikariDataSource (HikariPool-1)] to thread [http-bio-8080-exec-7] 
2015-04-13 14:57:48,581 [http-bio-8080-exec-7] TRACE org.springframework.transaction.support.TransactionSynchronizationManager - Bound value [[email protected]] for key [org[email protected]5019da97] to thread [http-bio-8080-exec-7] 
2015-04-13 14:57:48,581 [http-bio-8080-exec-7] TRACE org.springframework.transaction.support.TransactionSynchronizationManager - Initializing transaction synchronization 
2015-04-13 14:57:48,581 [http-bio-8080-exec-7] TRACE org.springframework.transaction.aspectj.AnnotationTransactionAspect - Getting transaction for [MyService.myMethod] 
2015-04-13 14:57:48,581 [http-bio-8080-exec-7] TRACE org.springframework.transaction.support.TransactionSynchronizationManager - Retrieved value [[email protected]] for key [org[email protected]5019da97] bound to thread [http-bio-8080-exec-7] 
2015-04-13 14:57:48,581 [http-bio-8080-exec-7] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Found thread-bound EntityManager [[email protected]] for JPA transaction 
2015-04-13 14:57:48,581 [http-bio-8080-exec-7] TRACE org.springframework.transaction.support.TransactionSynchronizationManager - Retrieved value [[email protected]] for key [HikariDataSource (HikariPool-1)] bound to thread [http-bio-8080-exec-7] 
2015-04-13 14:57:48,581 [http-bio-8080-exec-7] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Participating in existing transaction 
2015-04-13 14:57:48,581 [http-bio-8080-exec-7] TRACE org.springframework.transaction.aspectj.AnnotationTransactionAspect - Getting transaction for [MyDao.updateLastUpdatedTs] 
2015-04-13 14:57:48,581 [http-bio-8080-exec-7] DEBUG org.springframework.orm.jpa.EntityManagerFactoryUtils - Opening JPA EntityManager 
2015-04-13 14:57:48,582 [http-bio-8080-exec-7] DEBUG org.springframework.orm.jpa.EntityManagerFactoryUtils - Registering transaction synchronization for JPA EntityManager 
2015-04-13 14:57:48,582 [http-bio-8080-exec-7] TRACE org.springframework.transaction.support.TransactionSynchronizationManager - Bound value [[email protected]] for key [org[email protected]7cc8111c] to thread [http-bio-8080-exec-7] 
2015-04-13 14:57:48,608 [http-bio-8080-exec-7] TRACE org.springframework.transaction.support.TransactionSynchronizationManager - Retrieved value [[email protected]] for key [org[email protected]7cc8111c] bound to thread [http-bio-8080-exec-7] 
2015-04-13 14:57:48,608 [http-bio-8080-exec-7] TRACE org.springframework.transaction.aspectj.AnnotationTransactionAspect - Completing transaction for [MyDao.updateLastUpdatedTs] after exception: org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query 

Что на самом деле говорит, он создал транзакцию, он затем вступил в сделку (Есть два @Transactionals сейчас, один на уровне сервиса, а другой в DAO слое), а затем rollsback сделки , из-за исключения «Требуется транзакция».

Это орехи.

EDIT Ну, я нашел эту линию отладки:

2015-04-13 15: 27: 44074 [HTTP-био-8080-Exec-2] DEBUG org.springframework.orm.jpa .JpaTransactionManager - участники транзакция не удалась - маркировка существующей транзакции в качестве отката только

значения здесь: распространение = ТРЕБУЕМЫЙ, изоляция = УМОЛЧАНИЮ

Кажется, что существует транзакция, которая была проверена, как завершено, и присоединение транзакция не удалась, поэтому она отмечает ее как откат onl y, потому что он не мог присоединиться к нему.

ответ

2

Я изменил аннотации управляемой конфигурации, просто добавив прокси-целевого класса = «истинный», кажется, исправили проблему в одном из наших условий (ар-юго-востоке), который является Amazon Шанхаем, но что касается Европы (евро-запад), проблема все еще происходит. Это кошмар, все конфигурации в точности то же самое (это как раз указывает на другую БД & s3)

<tx:annotation-driven mode="aspectj" proxy-target-class="true" transaction-manager="transactionManager" /> 

РЕШЕНИЕ:

я наконец-то, в конце концов. Это исправляет (по крайней мере, по-видимому).

Причина: Очевидно, это как-то делать с инициализацией яровой и планирования некоторых задач до инициализации закончена, и что-то получил перепутались.

Я установил транзакционную аннотацию на уровне сервиса с использованием REQUIRES_NEW, чтобы создать новую транзакцию.

@Transactional(propagation = Propagation.REQUIRES_NEW) 

Убрано @Transactional с уровня DAO.

Мне также пришлось внести некоторые изменения в разъем, увеличивая maxThreads и максимальные/минимальные запасные потоки.

Я также изменил всю мою @Scheduled задачу инициализации, чтобы начать через 10 минут после запуска

кота

После того как все эти изменения, ошибка ушли.

Примечание Я также удалил предыдущее изменение: «прокси-целевой класс =» истинный «», и он по-прежнему работает нормально, так что не было на самом деле хорошим исправить здесь, но он может работать для вас, как это было для меня в некоторых случаях (фоновые задачи).

Как и примечание, другим изменением, которое я должен был сделать, чтобы сделать эту работу, было изменение @Repository на @Component, так как некоторые транзакции не выполняли записи в БД по запланированным задачам.

+0

вы можете принять свой собственный ответ. +1 для отправки ответа. – Lucky

+0

Это не позволит мне, это говорит не может через 2 дня. Но в любом случае это определило проблему для нашей азиатской среды (ap-south-east), но НЕ для Европы (eu-west), которая меня очень смущает. Все конфигурации точно такие же. –

+0

Включая точную конфигурацию базовой базы данных SQL? – chrylis

1

Не эксперт весной, но надеюсь, что это поможет.

Несколько дней назад, чтение Spring documentation за аналогичный вопрос, я нашел:

В частности, вам не нужен сервер приложений просто для декларативных транзакций через EJB. Фактически, , даже если ваш сервер приложений обладает мощными возможностями JTA, вы можете решить, что декларативные транзакции Spring Framework предлагают больше мощности и более продуктивную модель программирования, чем EJB CMT.

AFAIK, в наших услугах, мы объявляем сделки более конкретно, чтобы избежать некоторых из этих проблем, как:

@Transactional 
(
    propagation = Propagation.REQUIRED, 
    readOnly = false, 
    rollbackFor = Throwable.class 
) 

Если аннотации работают только в некоторых серверах, пытается быть конкретными при объявлении его в порядке для покрытия вашего сценария транзакций. Таким образом, я думаю, вы добьетесь такого же поведения на всех серверах.

+1

Мы не используем JTA. И аннотация @Transactional уже имеет некоторые значения по умолчанию. Аннотация работает, так как она запускает AnnotationSupportAspect, но все же исключение вызывается. Спасибо за помощь, хотя –

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