问题
I Want to write one new application with Spring boot using the database as MySQL + Mango and for messaging Spring Kafka.
I tried with Many POC for synchronizing the transaction between Kafka and DB but I failed in certain conditions and also I searched many Repositories, blogs to get at least one example. I didn't get any example still now.
if anyone gives at least one example or configurations it would be a nice reference in the future for all.
回答1:
Here you go...
@SpringBootApplication
public class So56170932Application {
public static void main(String[] args) {
SpringApplication.run(So56170932Application.class, args);
}
@Bean
public ApplicationRunner runner(KafkaTemplate<String, String> template) {
return args -> template.executeInTransaction(t -> t.send("so56170932a", "foo"));
}
@Bean
public ChainedKafkaTransactionManager<Object, Object> chainedTm(KafkaTransactionManager<String, String> ktm,
DataSourceTransactionManager dstm) {
return new ChainedKafkaTransactionManager<>(ktm, dstm);
}
@Bean
public DataSourceTransactionManager dstm(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean
public ConcurrentKafkaListenerContainerFactory<?, ?> kafkaListenerContainerFactory(
ConcurrentKafkaListenerContainerFactoryConfigurer configurer,
ConsumerFactory<Object, Object> kafkaConsumerFactory,
ChainedKafkaTransactionManager<Object, Object> ctm) {
ConcurrentKafkaListenerContainerFactory<Object, Object> factory = new ConcurrentKafkaListenerContainerFactory<>();
configurer.configure(factory, kafkaConsumerFactory);
factory.getContainerProperties().setTransactionManager(ctm);
return factory;
}
@Component
public static class Listener {
private final JdbcTemplate jdbcTemplate;
private final KafkaTemplate<String, String> kafkaTemplate;
public Listener(JdbcTemplate jdbcTemplate, KafkaTemplate<String, String> kafkaTemplate) {
this.jdbcTemplate = jdbcTemplate;
this.kafkaTemplate = kafkaTemplate;
}
@KafkaListener(id = "so56170932a", topics = "so56170932a")
public void listen1(String in) {
this.kafkaTemplate.send("so56170932b", in.toUpperCase());
this.jdbcTemplate.execute("insert into so56170932 (data) values ('" + in + "')");
}
@KafkaListener(id = "so56170932b", topics = "so56170932b")
public void listen2(String in) {
System.out.println(in);
}
}
@Bean
public NewTopic topicA() {
return TopicBuilder.name("so56170932a").build();
}
@Bean
public NewTopic topicB() {
return TopicBuilder.name("so56170932b").build();
}
}
and
spring.datasource.url=jdbc:mysql://localhost/integration?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.kafka.consumer.auto-offset-reset=earliest
spring.kafka.consumer.enable-auto-commit=false
spring.kafka.consumer.properties.isolation.level=read_committed
spring.kafka.producer.transaction-id-prefix=tx-
logging.level.org.springframework.transaction=trace
logging.level.org.springframework.kafka.transaction=debug
logging.level.org.springframework.jdbc=debug
and
mysql> select * from so56170932;
+------+
| data |
+------+
| foo |
| foo |
| foo |
| foo |
| foo |
| foo |
| foo |
| foo |
| foo |
+------+
9 rows in set (0.00 sec)
来源:https://stackoverflow.com/questions/56170932/transaction-synchronization-in-spring-boot-with-database-kafka-example