-
Notifications
You must be signed in to change notification settings - Fork 14
/
distributedTransactionConsistency.md
65 lines (54 loc) · 3.4 KB
/
distributedTransactionConsistency.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# 分布式事务解决方案笔记 Segment3
## 消息发送一致性
### 消息中间件的应用场景
- 消息中间件在分布式系统中的主要作用:异步通讯、解耦、并发缓冲
- 通过引入消息中间件来解耦应用间(服务间)的直接调用,同时也会起到异步通讯和缓冲并发的作用
### 消息发送和投递的不可靠性
分布式部署环境下,需要通过网络进行通讯,就引入了数据传输的不确定性,也就是CAP理论中的P(分区容错性的问题)
### 消息发送一致性
消息发送一致性:是指产生消息的业务动作与消息发送的一致。(也就是说,如果业务操作成功,那么由这个业务操作所产生的消息一定要成功投递出去,否则就丢消息)
### 消息发送一致性如何保障?
处理方式1
```
/** 支付订单处理**/
public void completeOrder() {
// 订单处理(业务操作)
orderBiz.process();
// 发送会记原始凭证消息(发送消息)
sendAccountingVoucherMsg();
}
```
1. 如果业务操作成功,执行消息发送前应用故障,消息发不出去,导致消息丢失(订单系统与会计系统的数据不一致);
2. 如果业务操作成功,应用正常,但消息系统故障或网络故障,也会导致消息发不出去(订单系统与会计系统的数据不一致);
处理方式2
```
/** 支付订单处理**/
public void completeOrder() {
// 发送会记原始凭证消息(发送消息)
sendAccountingVoucherMsg();
// 订单处理(业务操作)
orderBiz.process();
}
```
1. 这种情况下,更不可控,消息发出去了,但业务可能会失败(订单系统与会计系统的数据不一致);
这两种方式,都不能保证业务数据的一致性。
### JMS标准中的XA协议方式是否可以保障发送一致性?
- JMS协议标准的API中,有很多以XA开头的接口,其实就是前面课程讲到的支持XA协议(基于两阶段提交协议)的全局事务型接口。
- JMS中的XA系列接口,可以提供分布式事务支持。
- 但引用了XA方式的分布式事务,又会带来很多的局限:
- 要求业务操作的资源必须支持XA协议(并不是所有资源都支持XA)
- 两阶段提交协议的成本
- 持久化成本等DTP模型的局限性(全局锁定,成本高,性能低)
引入XA,违背了柔性事务的初衷!
### 变通的做法
![distributedTransactionQueue-min](https://s0.wailian.download/2019/01/11/distributedTransactionQueue-min.png)
1. 主动方应用先把消息发给消息中间件,消息状态标记为“待确认”;
2. 消息中间件收到消息后,把消息持久化到消息存储中,但并不向被动方应用投递消息;
3. 消息中间件返回消息持久化结果(成功/失败),主动方应用根据返回结果进行判断如何进行业务操作处理:
- 失败:放弃业务操作处理,结束(必要时向上层返回失败结果);
- 成功:执行业务操作处理;
4. 业务操作完成后,把业务操作结果(成功/失败)发送给消息中间件;
5. 消息中间件收到业务操作结果后,根据业务结果进行处理;
- 失败:删除消息存储中的消息,结束;
- 成功:更新消息存储中的消息状态为“待发送(可发送)”,紧接着执行消息投递;
6. 前面的正向流程都成功后,向被动方应用投递消息;