一、数据库事务
1.数据库事务:
1、事务是一个逻辑单元内的一系列操作。
2、事务分两种:读取事务(select)、修改事务(insert/update)
2.事务四大特性:
原子性(Atomicity): 事务内的所有操作,要么全部成功,要么全部失败回滚(不能对数据库有任何影响);
一致性(Consistency):事务前后,数据的完整性必须保持一致;
隔离性(Isolation):并发访问数据库时,事务与事务之间隔离,不会互相影响;下面有隔离级别
持久性(Durability):事务一旦被提交,则对数据库中数据的改变是永久性的(宕机断电不影响);
二、事务的隔离级别
1.数据读取的问题:
1、脏读(写-读问题):一个事务读到了另一个事务未提交的数据(可能是脏数据:这个数据有可能会回滚);
2、不可重复读(读-读问题):一个事务范围内,对同一个数据读取多次,结果不一样;
读取间隔内数据被其他事务修改并提交,区别脏读的是其他事务是否已提交改动;
3、幻读(读-写问题):事务先读取了一批数据,然后另一个事务又插入了新数据,导致结果跟预期不一致;
幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是插入新数据的场景。
2.事务的四种隔离级别:
1、读未提交(Read Uncommitted): 事务可以读到其他事务未提交的数据。 三种问题都有;
2、读已提交(Read Committed): 不能读其他事务没提交的数据。 解决脏读; (加了读锁和写锁)
3、可重复读(Repeatable read): 事务内多次读同一个数据,结果一样。 解决脏读、不可重复读; (读锁写锁+gap锁)
4、串行化(Serializable): 以锁表的方式限制并发操作,效率低; 解决脏读、不可重复读、幻读;
隔离级别越高,并发性能越低。
3.Mysql 默认可重复读:select @@tx_isolation REPEATABLE-READ
Oracle默认读已提交 Read Committed
4.Mysql是如何通过RR就解决幻读的
一致非锁定读(快照读):通过 MVCC(多版本并发控制) 为查询提供了一个基于时间的点的快照。
RR级别下,快照会在事务中第一次select语句执行时生成,且只有在本事务中对数据进行更改才会更新快照。所以期间其他事务insert的记录,当前事务是看不到的,也就避免了幻读的问题;
RC级别下,每一次查询都会提前更新快照。