en utilisant @Transactional de printemps sur une méthode qui permet également l'utilisation de aop: après avis

StackOverflow https://stackoverflow.com/questions/6344352

Question

i a essayé de voir s'il y a déjà une question similaire, mais n'a pas pu trouver si, ici il est.

nous avons un code existant où un BO fait des appels de méthode à plusieurs OTI utilisant la réflexion. j'ai modifié le code pour la simplicité.

@Transactional
class EndpointData1DAO implements DAO{
  void inserData() {
   // insert data 1
  }
}

@Transactional
class EndpointData2DAO implements DAO{
  void inserData() {
    // insert data 2
  }
}

class MachoBO {
 void handleEverything(String daoName) {
   DAO dao = getDAOUsingReflection(daoName);
   dao.insertData();
 }
}

le problème est, l'exigence a changé alors quand insertData () est appelée sur EndpointData1DAO, insertData de EndpointData2DAO doit être appelé ainsi.

je pourrais simplement ajouter EndpointData2DAO en tant que membre de EndpointData1DAO mais severly constitue une violation SRP et le rend laid.

donc j'ai écrit un @ExecuteAfter d'annotation (clazz = EndpointData2DAO.class, method = "insertData") qui obtient une instance de EndpointData2DAO et invoque insertData (), après la méthode de la classe dont elle annote est exécutée, en utilisant aop: après, de sorte que, compte tenu

@Transactional
@ExecuteAfter(clazz=EndpointData2DAO.class, method="insertData") 
class EndpointData1DAO implements DAO{
  void inserData() {
   System.out.println("insert1");
  }
}

@Transactional
class EndpointData2DAO implements DAO{
  void inserData() {
   System.out.println("insert2");
  }
}

class MachoBO {
 void handleEverything(String daoName) {
   DAO dao = getDAOUsingReflection(daoName);
   dao.insertData();
 }

1 2 seront imprimées sur l'appel machoBO.handleEverthing ( "Data1");

maintenant ma question est, volonté insertData () de EndpointData1DAO et EndpointData2DAO être dans la même transaction physique? autrement dit, sera une exception d'exécution dans insertData de EndpointData2DAO () rollback les données insérées par insertData EndpointData1DAO »()?

beaucoup merci d'avance ~ !!

Était-ce utile?

La solution

J'ai trouvé la réponse en exécutant effectivement un test.

En exécutant le code suivant, j'ai pu trouver le nom de l'opération en cours d'exécution.

ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
        Class tsmClass = contextClassLoader.loadClass("org.springframework.transaction.support.TransactionSynchronizationManager");
        String transactionName = (String) tsmClass.getMethod("getCurrentTransactionName", null).invoke(null, null);
        System.out.println(transactionName);

et compris que quand je mets @Transactional sur MachoBO comme ci-dessous,

@Transactional
class MachoBO {
 void handleEverything(String daoName) {
   DAO dao = getDAOUsingReflection(daoName);
   dao.insertData();
 }

depuis le @Transactional a une "portée de la méthode", quand machoBO.handleEverthing("Data1"); est appelé, inserData () des deux OTI exécutent sous le nom de transaction "MachoBO.handleEverthing".

Cependant, lorsque le MachoBO est pas annotées avec @Transactional, inserData () des deux OTI NE PAS partager la même portée de la méthode, et donc, sont exécutées dans des transactions séparées, à savoir "EndpointData1DAO.inserData" et "EndpointData2DAO.insertData".

Il convient de noter que (bien évident) que dans le cas quand un DAO est annotées avec @Transactional avec l'ensemble de propagation à REQUIRES_NEW, le insertData () des pistes de DAO dans une transaction séparée.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top