比如我有一账号里面有余额1000。然后发起一个事务,select * from account where uid = 1 发现余额1000。
结果这个时候另外一个事务已经提交账号减去800,这个时候呢实际账户只有200元,而且因为mvcc的原因你如果再去查询的话结果还是余额1000。
如果使用update account set money = money -1000 where uid = 1 那么账户里的钱就会变成负数了,这不就成生产事故了吗。
如果使用select * from acctoun for update 那么久会把表锁起来 。很难做到高可用。
那么最好的方法就是加一个字段version。 在所有修改数据库的时候都使它自动+1。
那么我们在select * from account where uid = 1的时候得到version的值。
在update的时候就变成update account set money = money -1000 where uid = 1 and version = 1 。如果返回结果是0
那么说明刚才结果已经改变,那么重试一次就好了。这个和cas的概念差不多。