找回密码
 立即注册
首页 业界区 业界 从银行转账失败到分布式事务:总结与思考 ...

从银行转账失败到分布式事务:总结与思考

茅断卉 2025-5-28 23:41:41
  思考这个问题的初衷,是有一次给朋友转账,结果我的钱被扣了,朋友没收到钱。而我之前一直认为银行转账一定是由事务保证强一致性的,于是学习、总结了一下分布式事务的各种理论、方法。
  事务是一个非常广义的词汇,各行各业解读都不一样。对于程序员,事务等价于Transaction,是指一组连续的操作,这些操作组合成一个逻辑的、完整的操作。即这组操作执行前后,系统需要处于一个可预知的、一致的状态。因此,这一组操作要么都成功执行,要么都不能执行;如果部分成功,部分失败,成功的部分需要回滚(rollback)。
  姊妹篇:再论分布式事务:从理论到实践
  本文地址:http://www.cnblogs.com/xybaby/p/7465816.html
关系型数据库事务

  大多数人可能和我一样,第一次听说事务是在学习关系型数据库(mysql、sql server、Oracle)的时候,在关系型数据库中,如果一组操作满足ACID特性,那么称之为一个事务。关于关系型数据库的ACID特性,不管是教材还是网络上都有大量的资料,这里只简单介绍。
  A(Atomic):原子性,构成事务的所有操作,要么都执行完成,要么全部不执行,不可能出现部分成功部分失败的情况
  C(Consistency):一致性,在事务执行前后,数据库的一致性约束没有被破坏。这里的一致性含义后面会详细解释
  I(Isolation):隔离性,数据库中的事务一般都是并发的,隔离性是指并发的两个事务的执行互不干扰,一个事务不能看到其他事务运行过程的中间状态
  D(Durability):持久性,事务完成之后,该事务对数据的更改会被持久化到数据库,且不会被回滚。
  我们举一个简单的转账的例子,用户A给玩家B转100块钱,那么涉及到两个操作:玩家A的账户扣100元,玩家B的账户加100元。即
UserA.account -= 100
UserB.account += 100
  原子性很好理解,这两个操作要么都成功,要么都不执行(更准确的是从效果上来看等价于都没有执行)。不可能出现用户A的钱减少了而用户B的钱没增加的情况,用户是不允许的;更不可能出现用户B的钱增加 而 用户A的钱没有减少的情况,银行是绝对不干的。
 
  一致性说一起来大家都懂,但是深究起来也是似懂非懂。ACID中的一致性,网络上的介绍都很模糊,都是说要处于一致的状态,那什么是一致的状态呢,比如转账操作中,A扣钱,B加钱,AB的钱的综合是一定的,这个是否属于ACID中的Consistency呢?我觉得不是的,Wiki Transaction_processing和Wiki: ACID分别是这么描述的
 Consistency: A transaction is a correct transformation of the state. The actions taken as a group do not violate any of the integrity constraints associated with the state.
The consistency property ensures that any transaction will bring the database from one valid state to another. Any data written to the database must be valid according to all defined rules, including constraints, cascades, triggers, and any combination thereof. This does not guarantee correctness of the transaction in all ways the application programmer might have wanted (that is the responsibility of application-level code), but merely that any programming errors cannot result in the violation of any defined rules.

  上面黑色加粗的部分指出,ACID中的一致性是指完整性约束不被破坏,完整性包含实体完整性(主属性不为空)、参照完整性(外键必须存在原表中)、用户自定义的完整性。用户自定义的完整性比如列值非空(not null)、列值唯一(unique)、列值是否满足一个bool表达式(check语句,如性别只能有两个值、岁数是一定范围内的整数等),例如age smallint CHECK (age >=0 AND age
您需要登录后才可以回帖 登录 | 立即注册