问答详情
源自:3-1 使用Spring声明式事务理论

想问下分布式服务应该如何添加事务?

想问下分布式服务应该如何添加事务?

提问者:听听米 2016-07-15 22:06

个回答

  • 原来我叫小土慕课网给我改了名字
    2016-07-16 15:27:49

    分布式事务的话主要有两种方式:

    (1)两阶段提交协议。就是在两个不同服务的上层有一个事务协调器(TC)。当发起一个请求时,TC先将消息写到本地日志里,之后向所有服务发起消息,本地日志是为例故障后恢复所用,相当于凭证的效果。所有服务收到消息后,执行具体本机事务,但不会进行commit,如果成功返回yes,失败返回no。同理,返回前都应把返回的消息写到日志里,当作凭证。TC手机所有返回的消息,如果所有服务都返回yes,那么给所有服务发送commit消息,如果有一个服务返回no,那么给所有服务发送abort消息,所有服务执行rollback。

    两阶段提交性能太差,不适合高并发的系统。因为涉及到多节点间的网络通信,通信时间长;并且事务时间相对于边长了,锁定的资源的时间也边长了,造成资源等待时间也增加好多。所以,往往会使用下面这种方式来解决分布式事务。

    (2)使用消息队列来避免分布式事务。拿支付宝向余额宝转账的例子来说。当支付宝在扣款事务提交之前,向实时消息服务请求发送消息,实时消息服务只记录消息数据不真正发送,只有消息发送成功后才会提交事务。当支付宝扣款事务被提交成功后,向实时消息服务确认发送。只有在得到确认发送指令后,实时消息服务才真正发送该消息。当支付宝扣款事务提交失败回滚后,向实时消息服务取消发送。在得到取消发送指令后,该消息将不会被发送。对应那些未确认的消息或者取消的消息,需要有一个消息状态确认系统定时去支付宝服务区查询这个消息的状态并进行更新,这样做是为了支付宝扣款事务被成功提交后,系统挂了,此时消息状态并未被更新为“确认发送”,从而导致消息不能被发送。


    使用消息队列来避免分布式事务的优点是消息数据独立存储,降低业务系统与消息系统间的耦合。缺点是一次消息发送需要两次请求,业务处理服务需要实现消息状态会查接口。