分布式事务实现

分布式事务实现

一、链式调用法

问题假设需要A、B、C三个服务中的a()、b()、c()方法并需要事务

1:再a()、b()、c()三个方法中搁置加入事务。然后进行链式调用

@Transactional
public void a() {
	//TODO 执行A服务的a()方法的方法体
	doSomething();
	//TODO 调用B服务的b()方法
	B.b();
}

@Transactional
public void B() {
	//TODO 执行B服务的b()方法的方法体
	doSomething();
	//TODO 调用C服务的c()方法
	C.c();
}

二、推送同步法

1:把当前需要调用的多个服务拼装成对象(List)

@Data
public class PostParam {
    public PostParam(){}
    public PostParam(String method){
        this.method = method;
    }

    public PostParam(String method, Object body){
        this.method = method;
        this.body = body;
    }

    private String method;

    private Object body;
}

2:通过mysql的insert方法把第1步中拼装的对象插入数据库中

1.事务表结构
@Data
@Accessors(chain = true)
@TableName("distributed_transactional")
public class DistributedTransactional implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 事务id
     */
    @TableId(value = "transactional_id", type = IdType.AUTO)
    private String transactionalId;

    /**
     * 事务内容,JSONAray格式
     */
    @TableField("content")
    private String content;

    /**
     * 操作人
     */
    @TableField("operate_user")
    private String operateUser;

    /**
     * 操作时间
     */
    @TableField("operate_time")
    private LocalDateTime operateTime;

    /**
     * 操作次数
     */
    @TableField("operate_number")
    private int operateNumber;

}
2.执行分布式事务的方法
public void excute (List<PostParam> list)  {
	DistributedTransactional transactional = new DistributedTransactional()
	transactional.setTransactionalId(UUID.getUUID());
	transactional.setContent(JSONObject.toJSONString(list));
	transactional.setOperateUser(loginUser);
	transactional.setOperateTime(LocalDateTime.now());
	//TODO 先把事务信息插入数据库中
	distributedTransactionalDao.inset(transactional);
	//TODO 此处处理业务流程
	for (PostParam param : list)  {
		//TODO 此处发送业务数据去具体的某个服务,并进行单个服务的业务处理
		sendPost(param);
	}
	//TODO 如果一切顺利,则删除本条事务数据
	distributedTransactionalDao.delete(transactional);
}

3:启动定时任务,读取数据库表中第2步中插入的数据,解析后继续第3步中失败的任务

@Component
@EnableScheduling
@Slf4j
public class TransactionalSchedule {
	@Autowired
	private DistributedTransactionalDao distributedTransactionalDao;
	
	@Scheduled(cron = "0 0 3 * * ?")
	public void excute() {
		//TODO 此处扫描全表的再2.2中处理失败的事务(如果数据可能太多,可以分页)
		List<DistributedTransactional> transactionalList = distributedTransactionalDao.selectList();
		for (DistributedTransactional dtl : transactionalList) {
			try{
				List<PostParam> list = JSONArray.parseArray(dtl.getContent(), PostParam.class);
				//TODO 此处处理业务流程
				for (PostParam param : list)  {
					//TODO 此处发送业务数据去具体的某个服务,并进行单个服务的业务处理
					sendPost(param);
				}
				//TODO 如果本次操作成功;删除此事务信息
				distributedTransactionalDao.delete(dtl);
			} catch (Exception e) {
				//TODO 如果本次依然操作失败;操作次数+1
				dtl.setOperateNumber(dtl.getOperateNumber()+1);
				distributedTransactionalDao.update(dtl);
			}
		}
	}
	
}

三、使用外部插件实现

1:使用seata:http://seata.io/zh-cn/docs/user/api.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值