我已将Spring Cloud Stream Kafka应用程序配置为使用事务(full source code available on Github):
spring:
application:
name: message-relay-service
cloud:
stream:
kafka:
binder:
transaction:
transaction-id-prefix: message-relay-tx-
producer:
configuration:
retries: 1
acks: all
key:
serializer: org.apache.kafka.common.serialization.StringSerializer
bindings:
output:
destination: transfer
contentType: application/*+avro
schema-registry-client:
endpoint: http://localhost:8081
schema:
avro:
subjectNamingStrategy: org.springframework.cloud.stream.schema.avro.QualifiedSubjectNamingStrategy
datasource:
url: jdbc:h2:tcp://localhost:9090/mem:mydb
driver-class-name: org.h2.Driver
username: sa
password:
jpa:
hibernate:
ddl-auto: create
database-platform: org.hibernate.dialect.H2Dialect
server:
port: 8085
此应用程序具有计划任务,该任务定期检查记录以使用@Scheduled
任务发送到数据库中。此方法用@Transactional
注释,并且主类定义@EnableTransactionManagement
。
但是,在调试代码时,我意识到没有执行KafkaTransactionManager,也就是说,没有适当的Kafka事务。有什么问题吗?
@EnableTransactionManagement
@EnableBinding(Source::class)
@EnableScheduling
@SpringBootApplication
class MessageRelayServiceApplication
fun main(args: Array<String>) {
runApplication<MessageRelayServiceApplication>(*args)
}
---
@Component
class MessageRelay(private val outboxService: OutboxService,
private val source: Source) {
@Transactional
@Scheduled(fixedDelay = 10000)
fun checkOutbox() {
val pending = outboxService.getPending()
pending.forEach {
val message = MessageBuilder.withPayload(it.payload)
.setHeader(KafkaHeaders.MESSAGE_KEY, it.messageKey)
.setHeader(MessageHeaders.CONTENT_TYPE, it.contentType)
.build()
source.output().send(message)
outboxService.markAsProcessed(it.id)
}
}
}
答案 0 :(得分:0)
在@EnableTransactionManagement
中看不到account-service
,只有在message-relay-service
中看不到。
无论如何,当前不支持您的方案;事务绑定器是为处理器设计的,处理器在该处理器上,消费者启动事务,消费者线程上发送的所有记录都参与该事务,消费者将偏移量发送到该事务,然后提交该事务。
它不是为仅生产者绑定而设计的;请针对活页夹打开GitHub问题,因为它应受支持。
我不确定为什么您看不到事务开始,但是即使这样,问题是@Transactional
将使用Boot的自动配置的KTM(和生产者工厂),并且绑定使用其他生产者工厂(您配置中的一个)。
即使正在进行交易,生产者也不会参与。