0

春ベースのTomcatサービスがあります。注釈ベースの休止状態マッピングを使用しており、複数のシャード データベースがあります。すべてのシャード データベースには同じテーブルがあり、Student と表示されます。@Transactionalアノテーションを使用してそれらにトランザクションを実装したい。

@Autowired
List<SessionFactory> sessionFactoryList;

@Transactional
public insertStudentBatch(List<Student> students) {

}

今、バッチ全体を挿入したいと思います。エラーが発生した場合は、すべてロールバックしてもらいたいです。それを行う最善の方法は何ですか?のように複数のTransactionManager修飾子を記述できます@Transactional("txManager1", "txManager2")か?

4

1 に答える 1

1

いいえ、残念ながら、Spring@Transactionalアノテーションは単一のトランザクション マネージャーに固有のものであり、説明したとおりに動作しません。

あなたが望む可能性が高いのは、基本的にマスターJTAトランザクションを開始し、次にそれぞれSessionFactoryに対して、シャードの特定のトランザクションマネージャーをそれぞれ呼び出して操作を実行する2PCコミットのJTAトランザクションです。

 @Service
 public class StudentBatchServiceImpl implements StudentBatchService {
   @Autowired List<StudentService> studentServices;
   @Transactional(value = "jtaTransactionManager")
   public void storeStudents(List<Student> students) {
     for(StudentService service : studentServices) 
       service.storeStudents(students);
   }
 }

 public interface StudentService {
   void storeStudents(List<Student> students);
 }

 public abstract AbstractStudentServiceImpl implements StudentService {
   protected void storeStudents(EntityManager em, List<Student> students) {
     for(Student student : students) {
       em.persist(student);
     }
   }
 }

 @Service
 public class Shard1StudentServiceImpl extends AbstractStudentServiceImpl {
   @PersistenceContext(name = "shard1")
   private EntityManager entityManager;
   @Override
   @Transactional(value = "shard1TransactionManager")
   public void storeStudents(List<Student> students) {
     storeStudents(entityManager, students);
   }
 }

JTA を使用して 2PC コミットをセットアップせずにこれを処理する方法は他にもあるかもしれませんが、通常はコンテナー管理トランザクション (JBoss、WebLogic など) で行います。これがアプローチになります。

余談ですが、すでに春の道を進んでいる場合は、チェックアウトすることをお勧めしますspring-batch。これは、多数のユースケースに対してバッチのような操作の適切なベースラインを提供します。上で説明したのは、 内の 1 つのケースの貧弱な実装ですspring-batch

アップデート

注釈の詳細を含む複数のシャード クラスの実装を作成する必要がないようにしたい場合は、XML 構成に頼って、単一のクラス実装を持つことができます。

 <bean id="shard1" class="default.ShardStudentServiceImpl">
   <property name="entityManager" ref="shard1EntityManager" />
   <property name="transactionManager" ref="shard1TransactionManager" />
 </bean>

ShardStudentServiceImplここでの唯一の違いは、XML で 25 個のシャードを定義する必要があることと、クラス内でトランザクションを開始、コミット、および管理するための独自のコードを作成する必要があることです。

上記の最終的な実装でアノテーションと組み合わせて抽象基本クラスを使用すると、私の更新は同じ宛先に到着します。実際、 を見るとspring-batch、エンティティ マネージャーとトランザクション マネージャーを単一のクラスへの入力プロパティとして指定することで、バッチ構成が同様の前提に従っていることがわかります。

于 2015-12-11T14:01:51.767 に答える