事物
- 事物是数据库最小的逻辑操作单位。
事务的ACID
1、原子性
一个事务必须被看做是一个不可分割的最小工作单元,事物中包含的操作要么都做,要么都不做,而不能只执行其中的一部分。
2、一致性
事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。这也是四个特性中比较难理解的一个。
从规范层面来讲,一致性是数据库对数据的约束,只有满足数据库的约束条件,才可以完成对数据的操作。比如关系数据库最常见的两类约束是“唯一性约束”和“完整性约束”,表格中定义的主键和唯一键都保证了指定的数据项绝不会出现重复,表格之间定义的参照完整性也保证了同一个属性在不同表格中的一致性。
从业务层面来讲,例如银行转账场景,转入和转出金额要平衡,是对业务层面的约束。
一致性的核心是”约束“,原子性是对单个事务的操作保障,一致性是多个事务对共享资源的竞争约束(规范)。
“Consistency in ACID”是事务提供的非常强有力的功能,它的核心是“约束”,而这个“约束”由数据库的使用者告诉数据库,使用者要求数据一定是符合这样或者那样的约束条件。当数据发生修改时,数据库会检查数据是否还符合约束条件,如果约束条件不再被满足,那么修改操作不会发生。关系数据库最常见的两类约束是“唯一性约束”和“完整性约束”,表格中定义的主键和唯一键都保证了指定的数据项绝不会出现重复,表格之间定义的参照完整性也保证了同一个属性在不同表格中的一致性。“Consistency in ACID”是如此的好用,以至于已经融化在大部分使用者的血液里了,使用者会在表格设计的时候自觉的加上需要的约束条件,数据库也会严格的执行这个约束条件。这就好像国家的计划生育政策,祖国规定了每个家庭最多只能生育两个孩子,那每个人都需要遵守。能不能生是能力问题,遵不遵守是...呃,就是必须遵守。链接:https://www.zhihu.com/question/56073588/answer/253106572
3、隔离性
一个事务内部的操作及使用的数据对其它并发事务通常是不可见的,并发执行的各个事务之间不能互相干扰。为什么说通常呢?因为在一些特定的情况下又是可见的,后面说到事务隔离级别再补充。
4、永久性
事物提交之后的修改操作是永久性的。
并发事务处理带来的问题
1、更新丢失(Lost Update)
当两个或多个事务选择同一行,然后基于最初选定的值更新该行值,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题,最后的更新覆盖来其他事务所做的更新。
2、脏读(Dirty Reads)
一个事务正在对一条记录做修改,在这个事务完成并提交前,这个条记录的数据就处于不一致的状态;这时另外一个事务也来读取同一条记录,如果不加控制,第二个事务读取来这些“脏”数据,并据此做进一步的处理,就会产生未提交的数据依赖关系。这种现象被形象的叫做“脏读”。
3、不可重复读(Non-Repeatable Reads)
一个事务在读取某些数据后的某个时间,再次读取以前读过的数据,却发现其读出的数据已经发生来改变、或某些记录已经被删除了,这种现象就叫做“不可重复读”。
4、幻读(Phantom Reads)
一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为“幻读”。
注:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表
隔离级别
1、读未提交 READ UNCOMMITTED
所有事物可以看到其他事物未提交的执行结果。
2、读已提交 READ COMMITTED
一个事物只能看见已经提交事物所做的改变。除 mysql 外其他多数数据库默认隔离级别。
3、可重读 REPEATABLE READ
同一事务的多个实例在并发读取数据时,会看到同样的数据行。mysql 默认隔离级别。
4、可串行化 Serializable
最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。
最后放图镇楼,加油,打工人。
好文章分享:
https://zhuanlan.zhihu.com/p/76743929
https://zhuanlan.zhihu.com/p/258078994