web-dev-qa-db-ja.com

春のトランザクション同期Kafka

kafkaトランザクションをリポジトリトランザクションと同期させたい:

@Transactional
public void syncTransaction(){
  myRepository.save(someObject)
  kafkaTemplate.send(someEvent)
}

マージ( https://github.com/spring-projects/spring-kafka/issues/37 )およびドキュメントによれば、これは可能です。それにもかかわらず、その機能を理解して実装するのに問題があります。 https://docs.spring.io/spring-kafka/reference/htmlsingle/#_transaction_synchronization の例を見ると、自分のイベントをリッスンするためにMessageListenerContainerを作成する必要があります。それでも、KafkaTemplateを使用してイベントを送信する必要がありますか? MessageListenerContainerはブローカーへの送信を禁止していますか?

そして、もし私がkafkaTemplateとkafkaTransactionManagerを正しく理解していれば、transactionIdPrefixを設定するトランザクションを有効にしなければならないのと同じプロデューサーファクトリーを使用する必要があります。そして、私の例では、messageListenerContainerのTransactionManagerをDataSourceTransactionManagerに設定する必要があります。あれは正しいですか?

私の観点からすると、kafkaTemplateを介してイベントを送信し、自分のイベントをリッスンし、kafkaTemplateを使用してイベントを再度転送するのは奇妙に見えます。

kafkaトランザクションとリポジトリトランザクションの簡単な同期の例と説明が得られたら、私は本当に役に立ちます。

7
Eike Behrends

リスナーコンテナーがKafkaTransactionManagerでプロビジョニングされている場合、コンテナーはダウンストリームkafkaテンプレートで使用されるプロデューサーを作成し、コンテナーはオフセットをトランザクションに送信します君は。

コンテナーに他のトランザクションマネージャーがある場合、コンテナーはプロデューサー(またはテンプレート)にアクセスできないため、オフセットを送信できません。

別の解決策は、@Transactional(データソースTMを使用)でメソッドに注釈を付け、kafka TM。

こうすることで、スレッドがコンテナーに戻る直前にDB txがコミットされ、コンテナーがオフセットをkafkaトランザクションに送信してコミットします。

例は フレームワークテストケース を参照してください。

8
Gary Russell

@Eike Behrendsはdb + kafkaトランザクションを持っているため、ChainedTransactionManagerを使用して次のように定義できます。

_@Bean
public KafkaTransactionManager kafkaTransactionManager() {
    KafkaTransactionManager ktm = new KafkaTransactionManager(producerFactory());;
    ktm.setTransactionSynchronization(AbstractPlatformTransactionManager.SYNCHRONIZATION_ON_ACTUAL_TRANSACTION);
    return ktm;
}


@Bean
@Primary
public JpaTransactionManager transactionManager(EntityManagerFactory em) {
    return new JpaTransactionManager(em);
}

@Bean(name = "chainedTransactionManager")
public ChainedTransactionManager chainedTransactionManager(JpaTransactionManager jpaTransactionManager,
                                                           KafkaTransactionManager kafkaTransactionManager) {
    return new ChainedTransactionManager(kafkaTransactionManager, jpaTransactionManager);
}
_

トランザクションdb + kafkaメソッドに注釈を付ける必要があります@Transactional("chainedTransactionManager")

(あなたはspring-kafkaプロジェクトの問題を見ることができます: https://github.com/spring-projects/spring-kafka/issues/4

あなたは言う :

私の観点からすると、kafkaTemplateを介してイベントを送信し、自分のイベントをリッスンし、kafkaTemplateを使用してイベントを再度転送するのは奇妙に見えます。

これを試しましたか?もしそうなら、あなたは例を提供できますか?

3
nader.h