什么是事务?
事务就是要保证一组数据库操作,要么全部成功,要么全部失败,在MySQL中,事务支持是在引擎层实现的
优点:支持严格的ACID属性(原子性(atomicity,或称不可分割性)、一致性(consistency)、隔离性(isolation,又称独立性)、持久性(durability))
原子性(atomicity):构成事务的所有操作,要么全部执行,要么全部不执行,不可能会出现一部分成功一部分失败的情况
一致性(consistency):在事务执行前后,数据库一致性没有被破坏
隔离性(isolation):数据库中的事务一般是并发的,隔离性是指并发的两个事务的执行互不干扰,一个事务不能看到其他事务运行过程的中间状态,通过配置事务隔离级别可以避免脏读、重复读等问题
持久性(durability):事务完成后,该事务对数据的更改会被持久化到数据库不会被回滚
事务隔离级别
- 读未提交(Read uncommitted):一个事务还没提交时,它做的修改就能被别的事务看到
事务A | 事务B |
select * from user; | |
insert into user(username) values('张三'); | |
select * from user; 张三 |
- 事务A读取到了未提交的事务B,这就是读未提交
- 读已提交(Read committed):一个事务提交之后,它做的变更才会被其他事务看到
事务A | 事务B |
select * from user; | |
insert into user(username) values('张三'); | |
select * from user; | |
commit; | |
select * from user; 张三 |
- 事务A只能读取到了已经提交的事务,这就是读已提交
- 可重复读(Repeatable read):个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。当然在可重复读隔离级别下,未提交变更对其他事务也是不可见的
事务A | 事务B |
select * from user; | |
insert into user(username) values('张三'); | |
commit; | |
select * from user; |
- 事务A读取不到已经提交的事务,这就是可重复读
- 串行化(Serializable ):“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。但是这种事务隔离级别效率低下,比较耗数据库性能
事务A | 事务B |
select * from user; | |
insert into user(username) values('张三'); | |
select * from user; | |
commit; | |
张三 |
- 只有当事事务A的操作提交过后,事务B才会继续执行
在事务的并发操作中可能会出现脏读,不可重复读,幻读
什么是脏读?
事务A | 事务B |
将n修改 n=1 | |
读取到修改的数据 n=1 | |
事务提交 |
事务B读取未提交的事务,这就是脏读
什么是不可重复读?
事务A | 事务B |
获取 n=0 | |
将n修改 n=1 | |
事务提交 | |
获取 n=1 |
事务A两次读取的数据不同,就是不可重复读
什么是幻读?
事务A | 事务B |
将n修改n=1 | |
读取到修改的数据 n=1 | |
事务提交 |
各类事务级别在面对并发情况下的情况 | | 脏读 | 不可重复读 | 幻读 | | --- | --- | --- | --- | | 读未提交 | √ | √ | √ | | 读已提交 | × | √ | √ | | 可重复读 | × | × | √ | | 串行化 | × | × | × |