2012-06-18 2 views
5

Spring wspiera programową transakcję, która zapewnia nam precyzyjną kontrolę nad zarządzaniem TX. Według wiosennej Dokumentacji, można użyć programowego zarządzania TX przez:
1. wykorzystując Wiosny TransactionTemplate:Wiosenne zautomatyzowane zarządzanie transakcjami?

transactionTemplate.execute(new TransactionCallbackWithoutResult() { 

protected void doInTransactionWithoutResult(TransactionStatus status) { 
    try { 
     updateOperation1(); 
     updateOperation2(); 
    } catch (SomeBusinessExeption ex) { 
     status.setRollbackOnly(); 
    } 
} }); 

2. dźwigni PlatformTransactionManager bezpośrednio (wstrzyknąć realizację PlatformTransactionManager do DAO):

DefaultTransactionDefinition def = new DefaultTransactionDefinition(); 
def.setName("SomeTxName"); 
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); 

//txManager is a reference to PlatformTransactionManager 
TransactionStatus status = txManager.getTransaction(def); 
try { 
    updateOperation1(); 
    updateOperation2(); 
} 
catch (MyException ex) { 
    txManager.rollback(status); 
    throw ex; 
} 
txManager.commit(status); 

dla w celu uproszczenia, załóżmy, że mamy do czynienia z operacją bazy danych JDBC.

Zastanawiam za wszelkie operacje na bazie danych stało w updateOperation1(),updateOperation2() w drugim fragmencie, albo jest on realizowany z JDBCTemplate lub JDBCDaoSupport, jeśli nie, to operacja jest faktycznie nie przeprowadzone w każdej transakcji, prawda?

Moja analiza polega na tym, że jeśli nie użyjemy JDBCTemplate lub JDBCDaoSupport, nieuchronnie utworzymy/pobierzemy połączenie z zarządzania zasobami. Połączenie, które otrzymujemy, nie jest oczywiście połączeniem używanym przez firmę PlatformTransactionManager do zarządzania transakcją.

Wykopałem kod źródłowy Spring i klasę skim związaną z tym, że PlatformTransactionManager spróbuje pobrać połączenie zawarte w ConnectionHolder, które w zamian zostanie pobrane z TransactionSynchronizationManager. Znalazłem również JDBCTemplate i JDBCDaoSupport, również postarać się o połączenie z podobnym rutyny z TransactionSynchronizationManager.

Ponieważ TransactionSynchronizationManager zarządza wiele zasobów w tym połączenia na gwint (w zasadzie korzystać Threadlocal aby zapewnić jeden wątek dostać swój własny, niepowtarzalny egzemplarz zarządzanego zasobu)

Więc myślę, że połączenie pobrane przez PlatformTransactionManager i JDBCTemplate lub JDBCDaoSupport jest takie samo, to może wyjaśnić, w jaki sposób wiosenna automatyzacja transakcji zapewnia ochronę strzeżonych transakcji przez updateOperation1(),updateOperation2().

Czy moja analiza jest prawidłowa? jeśli tak, dlaczego dokumentacja Spring nie podkreśla tego zastrzeżenia?

Odpowiedz

2

Tak, zgadza się.

Każdy kod, który wykorzystuje surowce Connection s powinien je uzyskać od DataSource w szczególny sposób w celu wzięcia udziału w transakcjach zarządzanych przez sprężynę (12.3.8 DataSourceTransactionManager):

Kod aplikacji jest wymagana w celu pobrania połączenia JDBC poprzez DataSourceUtils .getConnection (DataSource) zamiast standardowego DataSource.getConnection standardu Java EE.

Innym rozwiązaniem (jeśli nie można zmienić kod, który wywołuje getConnection()) jest owinąć DataSource z TransactionAwareDataSourceProxy.