1.什么是Saga?
第一次看到这个单词的时候一脸懵逼,因为字典上查到的意思完全驴头不对马嘴。。。
实际上,这个术语出自康奈尔大学的一篇论文:http://www.cs.cornell.edu/andru/cs711/2002fa/reading/sagas.pdf
最初这篇论文是为了解决分布式系统中的LLT(Long Lived Transaction),也就是长时运行事务的数据一致性问题的。这么说有点抽象,我们来举个具体的例子:
假如你在一个在线订票系统上订了一张机票,下单成功后,一般会给你留30分钟付款时间,如果你在30分钟内完成付款就可以成功出票,否则会被取消预定。也就是说,从下单到出票,最长可能需要30分钟,这就是传说中的LLT。用过数据库的同学肯定都知道,所谓“事务(Transaction)”,指的是一个原子操作,要么全部执行,要么全部回滚。那么问题来了,为了保证数据的一致性,我们是不是应该等待刚才那个LLT执行完成呢?这显然不现实,因为这意味着在这30分钟内,其他人都没办法订票了。。。于是,在1987年,康奈尔大学的两位大佬发表了一篇论文,提出了一个新的概念,叫做saga:
Let us use the term saga to refer to a LLT that can be broken up into a collection of sub-transactions that can be interleaved in any way with other transactions
具体是什么意思呢?还是以上面的订票系统为例,两位大佬说了,我们可以把这个LLT拆成两个子事务嘛,T1表示“预定”事务,T2表示“出票”事务。先执行T1,然后就可以把数据库释放出来了,其他人也可以正常订票了。如果用户在30分钟内完成了付款,那么再执行T2完成出票,这样整个事务就执行完毕了。假如超过了30分钟用户还没有付款怎么办?这时候需要执行一个“补偿”事务C1,用来回滚T1对数据库造成的修改。这几个子事务组合在一起,就叫一个saga:
当然,上面的例子只是最简单的情况,实际应用中的LLT可能非常复杂,包含非常多的子事务:
另外还有更复杂的并行saga,这里就不介绍了。看到这里,你可能会觉得,这好像也没啥嘛,本来就应该这么做啊。是的,如果你早出生30年,没准发论文的就就是你了^_^