分布式事物流程图
代码实现
rocketmq分布式事物消息 - 生产者
这里的版本借助maven helper插件,我们使用的rocketmq是4.4版本的,因此maven引入的依赖去插件里查看版本对应
- pom.xml
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.0.2</version>
</dependency>
- src/main/resources/application.yml
rocketmq:
name-server: xxx.xxx.xxx.xxx:9876
producer:
group: text-group
send-message-timeout: 300000
- src/main/java/com/runsky/paidui/controller/TeamLeaderController.java
@Resource
private RocketMQTemplate rocketMQTemplate;
private void sendTransactionalMessage() throws Exception{
// 2022/4/6 17:16 - mqtodo - 1 - 发送半消息
String transactionId = UUID.randomUUID().toString();
logger.info("------1 - sendTransactionalMessage - 发送半消息开始 :transactionId = " + transactionId + "------");
rocketMQTemplate.sendMessageInTransaction(
"text-half",
MessageBuilder
.withPayload("分布式事物消息测试")
// 可以设置多个Header
.setHeader(RocketMQHeaders.TRANSACTION_ID, transactionId)
.setHeader("text_id", 152)
.build(),
"这个arg有大用处"
);
logger.info("------1 - sendTransactionalMessage - 发送半消息结束 :transactionId = " + transactionId + "------");
}
- src/main/java/com/runsky/paidui/rocketMQ/TransactionListener.java
@RocketMQTransactionListener()
public class TransactionListener implements RocketMQLocalTransactionListener {
final static Logger logger = LoggerFactory.getLogger(TeamLeaderController.class);
@Override
// 2022/4/7 9:08 - mqtodo - 2 - 半消息发送成功
public RocketMQLocalTransactionState executeLocalTransaction(Message msg, Object arg) {
MessageHeaders headers = msg.getHeaders();
String transactionId = (String)headers.get(RocketMQHeaders.TRANSACTION_ID);
Integer textId = Integer.valueOf((String)headers.get("text_id"));
try {
logger.info("3 - executeLocalTransaction - 执行本地事物成功 :transactionId = " + transactionId);
// 2022/4/7 9:10 - mqtodo - 3 - 执行本地事物
/************************************************************
* @Author jking
* @Date 2022/4/7 9:23
* @Description - todo...
* 执行本微服务的事物逻辑service方法
* 方法(包括嵌套方法)均需要加标签 @Transactional(rollbackFor = Exception.class)
* 方法执行成功需要写 队列log表,供 MQServer 半消息回查使用
* 如果MQServer长期未得到半消息回复(断电等突发情况),会执行 checkLocalTransaction 方法进行回查
* 回查的依据为 队列log表
************************************************************/
// 2022/4/7 9:16 - mqtodo - 4 - 二次确认成功:提交
return RocketMQLocalTransactionState.COMMIT;
} catch (Exception e) {
logger.info("3 - executeLocalTransaction - 执行本地事物失败 :transactionId = " + transactionId);
// 2022/4/7 9:17 - mqtodo - 4 - 二次确认失败:回滚
return RocketMQLocalTransactionState.ROLLBACK;
}
}
@Override
// 2022/4/7 9:29 - mqtodo - 5 - MQServer未收到4的半消息回复进行回查
public RocketMQLocalTransactionState checkLocalTransaction(Message msg) {
MessageHeaders headers = msg.getHeaders();
String transactionId = (String)headers.get(RocketMQHeaders.TRANSACTION_ID);
logger.info("5 - checkLocalTransaction - MQServer未收到4的半消息回复进行回查 :transactionId = " + transactionId);
/************************************************************
* @Author jking
* @Date 2022/4/7 9:33
* @Description - todo...
* 6.检查本地事物状态
* 根据 transactionId 查询 队列log表
************************************************************/
// 2022/4/7 9:36 - 模拟一个 查询 队列log表 的返回值,实际生产为查询表的返回结果
String transactionLog = "";
if ( transactionLog != null ) {
logger.info("7 - checkLocalTransaction -二次确认成功:提交 :transactionId = " + transactionId);
// 2022/4/7 9:37 - mqtodo - 7 - 二次确认成功:提交
return RocketMQLocalTransactionState.COMMIT;
}
logger.info(