数据库事务Transaction有四大特点:ACID
本文主要介绍一下Atomicity原子性。
假设A、B和C在银行都有存款,存款额分别为:
现在A在ATM机上给B转账200元,然后又在手机客户端上给C转账400元,
刚在是串行执行的场景,没有任何问题,转账B成功,转账A失败,总金额不变(都是900元)。
但是如果两个转账操作是同时进行,由于A的初始金额是500,给C转账的时候不会发现余额不足,一个可能的执行逻辑如下:
这时候发现银行总存款从900元变成1200元,数据发生了不一致的情况。
有人会想到一个办法,转账的时候先做减法,再做加法,这样减法就会失败,就不会执行加法,这样银行总存款就是正确的。
这确实可以解决这个问题,但是如果考虑到可能会由于其他原因(网络、磁盘故障),在减法成功的前提下,最后一步加法失败,还是会导致总存款不一致。
也许有人想到了另外一种办法,就是如果发现最后A-400失败,可以恢复上一步操作,即让C-400,这样还是可以保证总存款是正确的。
这确实也是一个办法,但是同样如果考虑到可能会由于其他原因(网络、磁盘故障)导致最后恢复上一步操作的时候失败,还是会导致总存款不一致。
最后发现无论我们怎么设计流程,都无法100%保证数据正确性,根本的原因是:
这时候就需要用到事务的原子性。
原子性是指事务是一个不可再分割的工作单位,事务中的操作要么都发生,要么都不发生。
也就是说我们需要把B账号+200 & A账号-200
放到一个事务中执行,要么全部成功,要么全部失败,如下图所示:
B账号+200 & A账号-200
成功C账号+400 & A账号-400
失败最后银行存款总额保持900元,数据保证了正确性。