package main
import (
"fmt"
"log"
"sync"
"time"
)
// https://xiaomi-info.github.io/2020/01/02/distributed-transaction/
//消息表实现 分布式事务
//当系统 A 被其他系统调用发生数据库表更操作,首先会更新数据库的业务表,其次会往相同数据库的消息表中插入一条数据,两个操作发生在同一个事务中
//系统 A 的脚本定期轮询本地消息往 mq 中写入一条消息,如果消息发送失败会进行重试
//系统 B 消费 mq 中的消息,并处理业务逻辑。如果本地事务处理失败,会在继续消费 mq 中的消息进行重试,如果业务上的失败,可以通知系统 A 进行回滚操作
func main() {
wg.Add(2)
go handleMsg()
go retry()
business()
wg.Wait()
log.Println(list)
}
var wg = sync.WaitGroup{}
var msgChan = make(chan int, 10)
type Item struct {
Num int
Status int //1 等待回调 2 发消息失败 3 处理成功
}
var retryChan = make(chan int, 10)
var list []Item
func business() {
txFn := func(i int) {
status := 1
if i%2 == 0 { //模拟发消息失败
retryChan <- i
status = 2
} else {
msgChan <- i
}
list = append(list, Item{
Num: i,
Status: status,
})
}
for i := 0; i < 10; i++ {
time.Sleep(1)
txFn(i)
}
close(retryChan)
}
func handleMsg() {
for msg := range msgChan {
for k, item := range list {
if item.Num == msg {
fmt.Println("handle item:", item)
item.Status = 3
list[k] = item
}
}
}
wg.Done()
}
func retry() {
for msg := range retryChan {
msgChan <- msg
fmt.Println("retry msg:", msg)
}
close(msgChan)
wg.Done()
}
本地消息表模拟分布式事务
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 说到分布式事务,就会谈到那个经典的”账号转账”问题:2个账号,分布处于2个不同的DB,或者说2个不同的子系统里面,...