2013-02-22 17 views
15

Z pewnych powodów ręcznie wykonałem commit transakcji i wycofałem za pomocą Spring PlatformTransactionManager, muszę ustawić hak tak, aby akcja po zatwierdzeniu miała miejsce po transakcji zobowiązany.Tworzenie po zatwierdzeniu transakcji na wiosnę

Patrząc na:

void commit(TransactionStatus status) throws TransactionException; 

nie mogę zobaczyć, jak mogę określić transakcja przebiegła pomyślnie inne niż assumming go więc jeśli nie expception są wyrzucane.

Mogę użyć AOP jako jednej z opcji, ale co z programowaniem, może używając metody callback?

Odpowiedz

33

Można dostać dokładnie to, co chcesz przez prostszy sposób, z TransactionSynchronizationManager i TransactionSynchronization

Z TransactionSynchronizationManager, trzeba statycznych metod, aby uzyskać informacje na temat bieżącej transakcji, można zarejestrować TransactionSynchronization wich pozwala automatycznie wykonać post-commit jak nazwać

TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization(){ 
      void afterCommit(){ 
       //do what you want to do after commit 
      } 
}) 

Należy pamiętać, że TransactionSynchronization jest na per- podstawa wątku (która często nie stanowi problemu dla podstawowej prośby o dostęp do strony internetowej).

+0

OK, wydaje się to całkiem miłe ... więc jeśli jest związany z pojedynczym wątkiem, a wywołanie jest rekurencyjne ...powiedzmy, że pojedynczy wątek rozpoczyna transakcję rejestruje synchronizację (1 - po zatwierdzeniu), a następnie wywołuje inną metodę, która dołącza do tej transakcji, rejestruje synchronizację (2 - po zatwierdzeniu) .... kiedy zatwierdza ... myślę, że tylko jeden po zatwierdzeniu synchronizatora Zostałby zwolniony ... z powodu ich przechowywania w zestawie? .. może im źle, musiałbym przetestować ... – user1555190

+0

Obiekty 'TransactionSynchronization' są przechowywane jako listy według wątków, listy, które można pobrać za pomocą' TransactionSynchronizationManager. getSynchronizations() ' – Grooveek

+0

Uważam, że jest przechowywany jako zestaw, a następnie zwracana jako lista ... Ustaw synchronizuje .............. zwraca nową ArrayList (synchs) ..... po prostu myślę o dwóch po tym, jak zatwierdzenia będą strzelać ... – user1555190

1

W jednym z moich projektów z pewnych powodów musiałem również użyć PlatformTransactionManager. Więc zmusiłem do użycia org.springframework.transaction.support.TransactionTemplate.

http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/transaction/support/TransactionTemplate.html

Główną zaletą jest to, że jeśli wdrożyły PlatformTransactionManager prawidłowo, nie trzeba męczyć się z instrukcji commit/rollback. Przynajmniej kod źródłowy TransactionTemplate może ci pomóc, jeśli potrzebujesz bardziej konkretnej rzeczy.

To całkiem po prostu użyć:

config.xml

<bean name="transactionTemplate" 
      class="org.springframework.transaction.support.TransactionTemplate"> 
    <property name="transactionManager" ref="platformTransactionManager"/> 
</bean> 

MyServiceImpl.java

 

@Service 
public class MyServiceImpl implements MyService { 

    @Autowired 
    private TransactionTemplate transactionTemplate; 

    public Entity getSomethingWithTx(final long id) { 

     return transactionTemplate.execute(new TransactionCallback<Entity>() { 
      @Override 
      public Entity doInTransaction(TransactionStatus status) { 
       //TODO implement 
      } 
     }); 
    } 

+0

Ów naprawdę pomaga z ręcznego kodowania stronie rzeczy, ale jak to jest możliwe, aby powiedzieć pogoda transakcji został wycofany lub zatwierdzony z powodzeniem, widzę status.iscompleted() .. ale może to oznaczać pomyślne wycofanie lub pomyślne zatwierdzenie ...? – user1555190

+1

transakcja będzie wycofać się tutaj tylko w dwóch przypadkach: Kod zwrotna zgłasza wyjątek, który pozostawia doInTransaction czy istnieje niejawna wywołanie wycofywania (co jest zalecane i będzie prawdopodobnie wygeneruje UnexpectedRollbackException). Dlatego możesz bezpiecznie założyć, że jeśli getSomethingWithTx nie wyrzuci wyjątku, transakcja została zatwierdzona pomyślnie. – mrembisz

6

zgłosił odpowiedź Grooveek i Alexa komentarzu pod nią - Ja to tutaj, ponieważ połączone sugestie stanowią solidną i czystsze rozwiązanie, które jest trudno znaleźć wokół netto.

Korzystanie ze źródła 4+. jeśli potrzebujesz zwrotnej metody @Transactional po pomyślnym zobowiązuje tylko dodać, że na początku metody:

@Service 
public class OneService { 

    @Autowired 
    OneDao dao; 

    @Transactional 
    public void a transactionalMethod() { 
     TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter(){ 
      public void afterCommit(){ 
       //do stuff right after commit 
       System.out.println("commit!!!"); 

      } 
     }); 
     //do db stuff 
     dao.save(); 
    } 
} 
+1

Dzięki @Michail za odpowiedź. W przypadku wycofywania transakcji to podejście działa przy użyciu "afterCompletion (int status)" i sprawdzania statusu == TransactionSynchronization. STATUS_ROLLED_BACK – deep