Transaction 视为一个 Actor.
start_transaction(Order) ->
p1 = spawn(start_order(self, Order.subOrder1)) # 酒店
p2 = spawn(start_order(self, Order.subOrder2)) # 航空公司
p3 = spawn(start_order(self, Order.subOrder3)) # 汽车公司
wait_try_success(Order, [p1, p2, p3])
wait_try_success(Order, Actors) ->
receive
try_success ->
if all_tried
Actors.forEach(actor => actor ! confirm)
wait_confirm_success(Order, Actors)
try_failed ->
Actors.forEach(actor => actor ! cancel)
timeout ->
Actors.forEach(actor => actor ! cancel)
wait_confirm_success(Order, Actors) ->
receive
confirm_success ->
if all_confirmed
done
confirm_failed ->
Actors.forEach(actor => actor ! cancel)
timeout ->
Actors.forEach(actor => actor ! cancel)
每个任务视为一个 actor,
start_order(Transaction, Order) ->
try()
Transaction ! try_success
wait_confirm(Transaction, Order)
wait_confirm() ->
receive
confirm ->
confirm()
Transaction ! confirm_success
timeout ->
cancel()
Transaction ! failed
cancel ->
cancel()
发起人启动 Transaction, 该 Transaction 启动 order actor, 并进入 try.
order actor 收到订单时, 执行 try, 等待 confirm.
Transaction 收集满所有相关 actor 的 try_success 后, 通知 confirm.
收集齐所有 confirm_success 后, 事务完成.
- 如收到 confirm_failed 后 try_failed, 则群发 cancel.
- 如超时, 亦群发 cancel.
order actor 在 wait_confirm 状态, 如超时或收到 cancel 均回滚.
当然, TCC 也无法解决 confirm 成功的 actor 再也联系不上的问题. 联系不上只能通过可靠送达的 MQ 来解决, 如节点 confirm 后再也不开机了也就无可奈何了.