2012-06-18 1 views
5

Spring prend en charge la transaction programmatique qui nous donne un contrôle précis de la gestion TX. Selon la documentation de printemps, on peut utiliser la gestion TX programmatique:
1. utilisant le TransactionTemplate de printemps:Mise en garde de gestion des transactions programmatiques de printemps?

transactionTemplate.execute(new TransactionCallbackWithoutResult() { 

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

2. tirant parti PlatformTransactionManager directement (injecter une mise en œuvre de PlatformTransactionManager en 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); 

pour Par souci de simplification, disons qu'il s'agit d'une opération de base de données JDBC.

Je me demande pour toutes les opérations de base de données se sont produites à updateOperation1(),updateOperation2() dans le second extrait, soit il est mis en œuvre avec JDBCTemplate ou JDBCDaoSupport, sinon, l'opération est en réalité pas effectué dans une transaction, est-il? Mon analyse est que si nous n'utilisons pas JDBCTemplate ou JDBCDaoSupport, nous allons inévitablement créer/récupérer la connexion à partir de la gestion des sources de données. la connexion que nous obtenons n'est bien sûr pas la connexion utilisée par PlatformTransactionManager pour gérer la transaction.

Je creusèrent le code source de printemps et écumer la classe ont été trouvés que PlatformTransactionManager va essayer de récupérer une connexion contenue dans ConnectionHolder qui en retour récupéré à partir TransactionSynchronizationManager. J'ai aussi trouvé JDBCTemplate et JDBCDaoSupport, également essayer d'obtenir une connexion avec la routine similaire de TransactionSynchronizationManager.

Parce que TransactionSynchronizationManager gère un grand nombre de connexion comprenant des ressources par thread (utiliser essentiellement Threadlocal pour assurer un thread obtenir sa propre instance unique de la ressource gérée)

Donc, je pense que la connexion récupérée par PlatformTransactionManager et JDBCTemplate ou JDBCDaoSupport est exactement la même, cela peut expliquer comment la transaction programmatique de printemps assurer updateOperation1(),updateOperation2() ont été gardés par transaction.

Mon analyse est-elle correcte? si c'est le cas, pourquoi la documentation de Spring n'a pas insisté sur cette mise en garde?

Répondre

2

Oui, c'est correct.

Tout code qui utilise Connection premières s devraient les obtenir du DataSource de façon spéciale afin de participer à des opérations gérées par Spring (12.3.8 DataSourceTransactionManager):

code d'application est nécessaire pour récupérer la connexion JDBC par DataSourceUtils .getConnection (DataSource) au lieu de DataSource.getConnection standard de Java EE.

Une autre option (si vous ne pouvez pas modifier le code qui appelle getConnection()) est d'envelopper votre DataSource avec TransactionAwareDataSourceProxy.

Questions connexes