2015-01-22 3 views
2
.

. Невозможно предотвратить откат транзакции после исключения RuntimeException. Мой env - Spring 4.1 + Hibernate 3.6 + JTA (WebSphereUwTransactionManager), работающий на Websphere 8.0.Весенние транзакции. Предотвращение отката после исключенных исключений (RuntimeException).

Прежде всего, простой случай, который ведет себя так, как ожидалось. Поскольку I улавливает RuntimeException, транзакция фиксируется, и новый ресурс создается успешно.

@Service("fooService") 
public class FooServiceImpl implements IFooService { 

    @Transactional 
    @Override 
    public void doStuff(Resource res){ 
     authService.createResource(res, "ADMIN"); 
     try { 
      throw new RuntimeException("SOMETHING"); 
     } catch (RuntimeException e) { 
      e.printStackTrace(); 
     } 
    } 

Следующее в порядке. Объявляю noRollbackFor и давайте совершать сделки:

@Transactional(noRollbackFor=RuntimeException.class) 
    @Override 
    public void doStuff2(Resource res){ 
     authService.createResource(res, "ADMIN"); 
     throw new RuntimeException("SOMETHING"); 
    } 

И, наконец проблемные один. Разница в том, что в этом случае исключение возникает при втором вызове authService.createResource. FYI, authService.createResource отмечен только как @Transactional, поэтому применяется настройка распространения по умолчанию, и она должна присоединяться к транзакции вызывающей службы.

@Transactional(noRollbackFor=RuntimeException.class) 
    @Override 
    public void doStuff12(Resource res){ 

     authService.createResource(res, "ADMIN"); 
     try{ 
      res.setName("EXISTING-RESOURCE"); 
      authService.createResource(res, "ADMIN"); 
     }catch(RuntimeException e){ 
      e.printStackTrace(); 
     } 
    } 

Несмотря поймать RuntimeException и объявив noRollbackFor атрибут транзакции всегда rollsback. Любое объяснение ??

Входа Информация трассировки:

org.springframework.transaction.jta.WebSphereUowTransactionManager DEBUG - Creating new transaction with name [null]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '',+com.myorg.webapps.exception.ElementoYaExistente 
org.springframework.transaction.jta.WebSphereUowTransactionManager DEBUG - Invoking WebSphere UOW action: type=1, join=false 
org.springframework.transaction.support.TransactionSynchronizationManager TRACE - Initializing transaction synchronization 
org.springframework.transaction.interceptor.TransactionInterceptor TRACE - Getting transaction for [com.myorg.test.service.impl.FooServiceImpl.doStuff12] 
org.springframework.transaction.jta.WebSphereUowTransactionManager DEBUG - Creating new transaction with name [null]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '' 
org.springframework.transaction.jta.WebSphereUowTransactionManager DEBUG - Invoking WebSphere UOW action: type=1, join=true 
org.springframework.transaction.interceptor.TransactionInterceptor TRACE - Getting transaction for [com.myorg.authmgr.service.impl.AuthorizationServiceImpl.createResource] 
org.springframework.transaction.jta.WebSphereUowTransactionManager DEBUG - Returned from WebSphere UOW action: type=1, join=true 
org.springframework.transaction.jta.WebSphereUowTransactionManager DEBUG - Creating new transaction with name [null]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '' 
org.springframework.transaction.jta.WebSphereUowTransactionManager DEBUG - Invoking WebSphere UOW action: type=1, join=true 
org.springframework.transaction.interceptor.TransactionInterceptor TRACE - Getting transaction for [com.myorg.authmgr.service.impl.AuthorizationServiceImpl.createResource] 
org.springframework.transaction.interceptor.RuleBasedTransactionAttribute TRACE - Applying rules to determine whether transaction should rollback on java.lang.Runtime: Couldn't create the resource, it already exists: EXISTING-RESOURCE 
org.springframework.transaction.interceptor.RuleBasedTransactionAttribute TRACE - Winning rollback rule is: null 
org.springframework.transaction.interceptor.RuleBasedTransactionAttribute TRACE - No relevant rollback rule found: applying default rules 
org.springframework.transaction.jta.WebSphereUowTransactionManager DEBUG - Returned from WebSphere UOW action: type=1, join=true 
org.springframework.transaction.jta.WebSphereUowTransactionManager TRACE - Triggering beforeCommit synchronization 
org.springframework.transaction.jta.WebSphereUowTransactionManager TRACE - Triggering beforeCompletion synchronization 
org.springframework.transaction.support.TransactionSynchronizationManager TRACE - Clearing transaction synchronization 
org.springframework.transaction.jta.WebSphereUowTransactionManager DEBUG - Returned from WebSphere UOW action: type=1, join=false 

ответ

3

Насколько я знаю, как только исключение во время выполнения выбрасываются из транзакционной методы и перехватываются перехватчиком сделки, транзакция помечена как только откат. Даже если этот транзакционный метод вызывается из другого транзакционного метода.

Это имеет смысл для меня: если внутренний метод не может восстановиться из исключения, он не может восстановиться, а внешний метод не должен делать так, как будто ничего не произошло.

Если вы ждете сделки не откатить, вы можете

  • сделать внутренний метод нетранзакционными
  • настроить внутренний метод не откатить на это исключение
  • имеют две внутренние методы :
    • тот, который является транзакционным и предназначен для вызова, когда транзакции еще нет, и который просто делегирует второй код
    • один, который не является транзакционной, и предназначен для вызова в рамках уже существующей транзакции
+1

Что вы говорите, вид имеет смысл. Однако странно, что объединенная транзакция не учитывает правило родителя 'noRollbackFor = RuntimeException.class'. Для меня было бы логичнее, что он придерживался конфигурации всей транзакционной области ... В этом случае внутренний метод ДОЛЖЕН быть транзакционным и ДОЛЖЕН откат при вызове самостоятельно, поэтому я должен исключить два первых предложения , О третьем, Spring - это заставляет нас предлагать две реализации, одну транзакционную, одну не транзакционную, в наших API-интерфейсах для управления этими (не столь необычными) ситуациями, которые неэлегантные – codependent