0%

数据库事务中“原子性”的简单理解和例子

事务具有4的个基本特性:原子性、一致性、隔离性、持久性。其中原子性(Atomicity)的概念表示事务中的一系列操作要么全部成功,要么全部失败,不存在“部分成功”的状态。

概念

原子性表示事务中的一系列操作是不可分割的,要么全部成功,要么全部失败。如果事务执行中途出现意外,已经执行的修改会被撤销, 回滚到事务开始前的状态。

例子

  • 对于事务中的多条SQL,要么全部成功,要么全部失败。

    例如A向B转账100元需要执行2条SQL:

    1. A余额减少100元
    2. B余额增加100元

    这2条SQL必须同时成功,或者同时失败,否则会导致账目对不上。

  • 一条SQL更新多条记录时,要么全部记录更新成功,要么全部都没有更新。

    例如,给所有VIP用户增加积分,要么全部都增加了,要么全部没增加。

  • 对于某一个数据页(或者某一行记录、某个字段),需要完整更新,不能只写入了一部分。

    例如,插入一段10Kb的字符串到数据库,磁盘写入到6Kb的时候断电了。重新启动数据库之后,需要能恢复到修改前的状态,或者完整写入100Kb字符串。

解决的问题

事务执行过程中,可能出现很多意外,例如用户回滚了事务、连接断开、断电、数据库崩溃、操作系统崩溃、死锁等等,导致事务被中断执行。
原子性可以在事务被中断执行时,撤销已经执行的修改,从而保证不会出现上述例子中的账目对不上、数据完整性被破环等问题。

实现原理

  • 回滚
    数据库需要同时保存修改前、修改后的信息,需要回滚时,把修改前的信息还原即可。在Innodb中,使用undo日志来实现回滚操作。

  • Doublewrite Buffer
    数据库将数据页写入到磁盘前,先写一份到Doublewrite Buffer。如果在写入数据页到磁盘时发生崩溃,重启后可以在Doublewrite Buffer中找到一份正确的数据,并将数据恢复到对应的数据页。

参考