分布式事务¶
问题描述¶
远程调用服务成功,但是没有返回结果
导致:订单回滚了,但是远程服务已经实现了
远程调用服务之后的流程出现异常
但是已执行的远程调用不能回滚
事务传播¶
本地事务失效问题¶
同一个对象内,事务方法不能互相调用。因为绕过了代理对象。
分布式事务解决方案一: SEATA¶
AT模式(全局锁):
- 创建 undo_log
CREATE TABLE `undo_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`branch_id` bigint(20) NOT NULL,
`xid` varchar(100) NOT NULL,
`context` varchar(128) NOT NULL,
`rollback_info` longblob NOT NULL,
`log_status` int(11) NOT NULL,
`log_created` datetime NOT NULL,
`log_modified` datetime NOT NULL,
`ext` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
- 安装
- 使用 seata DataSourceProxy代理自己的数据源
- 在每个微服务中导入 .conf
- 在分布式大事务入口标注 @GlobalTransactional
- 在远程调用的小事务标注 @Transactional
分布式事务解决方案二:可靠消息 + 最终一致性¶
- 业务处理服务在业务事务提交之前,向实时消息服务请求发送消息,实时消息服务只记录消息数据,而不是真正的发送。
- 业务处理服务在业务事务提交之后,向实时消息服务确认发送。
- 只有在得到确认发送指令后,实时消息服务才会真正发送。