如果只是一堆数据库的操作,那还可以用事务来解决。
如果涉及到的操作是多个层面的,如何保证其一致性呢?
如果按顺序一件一件地做,前一件做失败了,就不做后面的,危害会小一些。但最好还是把前面做成的事给撤销掉,而这很难,几乎做不到(退款提交了,就不可能追回退款;数据更新了,老数据就丢失了,不能恢复成原始数据;短信发出去了,也无法撤回)
更严重的是,一旦向支付方式提交退款如果成功了,而本地数据库却更新失败,没有记录到“已退款”,那必然就会形成坏账。
所以这一类问题究竟应该怎么处理才合适?
请大家就以我举例的退款问题来回答吧。
所有事务都需要可回滚,像你例子中短信发了就不可能回滚,而且短信发了有没有成功,发成功了对方有没有收到?这都不是确定性的,所以,把这种加到事务一致性是不可行的。
对于可回滚的,只要做到最终一致就行,怎么做就根据各自需要决定了,比如使用MQ或者文本日志。用你的例子来说:
提交退款 -> 更新数据。
在业务逻辑上,更好的应该是 “更新数据,然后提交退款”,因为更新数据可回滚,但退款一般是不可回滚。
做法上,简单的就可以借助数据库事务来更新数据,,然后去退款,得到退款结果后,再commit数据库。
复杂的可以用二阶段提交等方式。
最后,提醒一下,要真正实现自动的最终一致,需要极高的可用性,一般场景下,记下log,偶尔有问题,通过脚本事务对帐就好了。