为何Spring Boot中JDBC出站网关/适配器需显式事务通知才能提交?
问题:Spring Boot 2.7.10中Spring Integration JDBC出站组件事务不提交问题
现象描述
- 使用Spring Boot 2.7.10结合XML配置Spring Integration时,JDBC出站网关/适配器必须在
<int-jdbc:request-handler-advice-chain>中配置带有<tx:attributes>子元素的显式<tx:advice>,否则事务无法提交,数据修改会丢失。 - 若省略
<tx:advice>,或使用空的<tx:advice />(期望沿用默认事务属性),即便SQL语句执行成功,数据库也不会有任何写入。调试可发现org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionInfo)方法中的txInfo为null。
传统Spring应用与Spring Boot的差异
在非Spring Boot的传统XML配置Web应用中:
- 无需显式配置
<tx:advice>,JDBC出站组件会自动提交事务; - 若要给入站适配器的轮询器开启事务,只需配置空的
<tx:advice>,即可自动启用PROPAGATION_REQUIRED传播属性的读写事务,这与Spring Framework文档描述一致。
原因推测
Spring Boot的自动配置机制可能跳过了XML配置场景下,Spring Integration JDBC组件所需的默认事务定义初始化步骤,导致未显式配置<tx:attributes>时,事务切面无法生成有效的事务信息(txInfo),最终无法触发事务提交逻辑。
解决方案
必须在<int-jdbc:request-handler-advice-chain>中配置包含<tx:attributes>的<tx:advice>,示例配置如下:
<int-jdbc:outbound-channel-adapter id="myAdapter" channel="inputChannel" data-source="dataSource" query="UPDATE `MyTable` SET `param1` = :param1, `param2` = :param2 WHERE `id` = :id" sql-parameter-source-factory="myParameterSourceFactory"> <int-jdbc:request-handler-advice-chain> <bean class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice"> <property name="retryTemplate" ref="myRetryTemplate" /> </bean> <tx:advice transaction-manager="transactionManager"> <tx:attributes> <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice> </int-jdbc:request-handler-advice-chain> </int-jdbc:outbound-channel-adapter>
通过显式指定<tx:method>定义事务属性,确保事务切面能生成有效的事务信息并触发提交操作。
内容的提问来源于stack exchange,提问作者Mauro Molinari
相关产品推荐
相关产品推荐

