3

私はすでに同様の質問があるかどうかを確認しようとしていましたが、それを見つけることができませんでした、ここにあります。

単一のBOがリフレクションを使用して多くのDAOへのメソッド呼び出しを行うレガシーコードがあります。簡単にするためにコードを変更しました。

@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();
 }
}

問題は、要件が変更されたため、EndpointData1DAOでinsertData()が呼び出されたときに、EndpointData2DAOのinsertDataも呼び出される必要があることです。

EndpointData2DAOをEndpointData1DAOのメンバーとして追加するだけでもかまいませんが、SRPに著しく違反し、見苦しくなります。

だから私はアノテーション@ExecuteAfter(clazz = EndpointData2DAO.class、method = "insertData")を書きました。これは、EndpointData2DAOのインスタンスを取得し、アノテーションを付けるクラスのメソッドが実行された後、aop:afterを使用してinsertData()を呼び出します。 、与えられたように

@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は、machoBO.handleEverthing( "Data1");を呼び出すと出力されます。

今私の質問は、EndpointData1DAOとEndpointData2DAOのinsertData()は同じ物理トランザクションにあるのでしょうか?つまり、EndpointData2DAOのinsertData()のランタイム例外は、EndpointData1DAOのinsertData()によって挿入されたデータをロールバックしますか?

よろしくお願いします〜!!

4

1 に答える 1

0

実際にテストを実行して答えを見つけました。

以下のコードを実行することで、現在実行中のトランザクションの名前を知ることができました。

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);

以下のように @Transactional を MachoBO に配置すると、

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

@Transactional には「メソッド スコープ」があるため、machoBO.handleEverthing("Data1");が呼び出されると、両方の DAO の inserData() がトランザクション名「MachoBO.handleEverthing」で実行されます。

ただし、MachoBO に @Transactional のアノテーションが付けられていない場合、両方の DAO の inserData() は同じメソッド スコープを共有しないため、別のトランザクション、つまり「EndpointData1DAO.inserData」と「EndpointData2DAO.insertData」で実行されます。

ただし、DAO に @Transactional のアノテーションが付けられ、伝播が REQUIRES_NEW に設定されている場合、DAO の insertData() は別のトランザクションで実行されることに注意してください。

于 2011-06-17T02:54:55.157 に答える