什么是事务?
事务, 即数据库事务. 是数据库管理系统执行过程中的一个逻辑单位, 由一个有限的数据库操作序列构成.
通常, 事务的正确执行会使数据库从一种状态转换为另一种状态.
事务的特性 (ACID 原则)
原子性 (atomicity) 即不可分割性, 事务要么全执行, 要么全不执行.
一致性 (consistency) 事务的执行使得数据库从一种正确状态转换成另外一种正确状态.
隔离性 (isolation) 在事务正确提交之前, 不允许把事务对该数据的改变提供给任何其他事务.
持久性 (durability) 事务正确提交之后, 其结果将永远保存在数据库之中.
并发状态下事务会产生的问题
并发状态解释为当事务 A 和事务 B 对同一资源进行操作时, 可能会遇到很多的问题.
脏读 (针对未提交数据)
即事务 A 读到了事务 B 还没有提交的数据. 如果事务 A 对数据进行了更新, 但是事务 A 并没有提交, 但是事务 B 这个时候看到了事务 A 没有提交的更新. 当事务 A 进行了回滚, 那么刚刚事务 B 看到的数据就是脏数据. 也就是脏读.
例子:
A 给 B 转了 100 万, 但是 A 还没有提交, 此时 B 查询自己账户, 多了 100 万. 然后 A 发现转错人了, 回滚了事物. 然后 B 100 万就没了. 在这个过程中 B 查到了没有提交的数据 (多出的 100 万), 这就是脏读.
不可重复读 (在一个事务里面读取了两次某个数据, 读出来的数据不一致, 针对修改操作)
即同一事务在事务执行过程中对同一个数据进行了多次读取, 但是每一次读取的数据结果都不相同. 原因是在两次读取间隔, 数据别其他人修改了, 导致了统一事务两次读取结果不一致.
例子:
A 查询银行余额为 100 万, B 这个时候取走了 50 万, 此时余额变成了 50 万, A 再一次查询余额, 变成了 50 万. 对 A 而言两次结果不一致就是不可重复读.
幻读 (在一个事务里面的操作中发现了未被操作的数据, 针对增删操作)
即在事务 A 多次读取数据集的过程中中, 事务 B 对数据进行了新增操作或者删除操作, 导致事务 A 多次读取的数据集不一致.
例子:
A 修改当前公司所有职员信息的时候, B 向其中插入了一个新的职员, 这个时候 A 提交的时候发现了一个自己没有修改过的职员的信息, 对 A 而言就像是产生了幻觉.
事务的隔离级别
为了应对上面并发情况下出现的问题, 事务的隔离级别就产生了. 当事务的隔离级别越高的时候, 上面的问题就会越少, 但是性能消耗也会越大. 所以在实际生产过程中, 要根据需求去确定隔离级别.
四种隔离级别
READ_UNCOMMITTED
读未提交, 即能够读取到没有被提交的数据, 所以很明显这个级别的隔离机制无法解决脏读, 不可重复读, 幻读中的任何一种.
READ_COMMITED
已提交, 即能够读到那些已经提交的数据, 能够防止脏读, 但是无法解决不可重复读和幻读的问题.
REPEATABLE_READ
重复读取, 即在数据读出来之后加锁, 类似 "select * from XXX for update", 明确数据读取出来就是为了更新用的, 所以要加一把锁, 防止别人修改它. REPEATABLE_READ 的意思也类似, 读取了一条数据, 这个事务不结束, 别的事务就不可以改这条记录, 这样就解决了脏读, 不可重复读的问题, 但是幻读的问题还是无法解决.
SERLALIZABLE
串行化, 最高的事务隔离级别, 不管多少事务, 挨个运行完一个事务的所有子事务之后才可以执行另外一个事务里面的所有子事务, 这样就解决了脏读, 不可重复读和幻读的问题了.
来源: https://www.cnblogs.com/jyroy/p/11106609.html