文章目录
一、事务
1、什么是事务?
概念:
2、事务的使用
begin/start transaction -- 开启事务
执行多个SQL语句
commit; --提交
--(开启事务后,中间的这些SQL不会立即执行,而是先等着,
--等commit后再全部执行,保证了事务的原子性)
rollback -- 回滚
二、事务的性质(ACDI)
1、原子性(Atomic)
2、一致性(Consist)
3、持久性(Durable)
4、隔离性(Isolated)-重点难点
三、隔离性的深度剖析
1、隔离与并发的关系
- 要理解的一个重点:隔离程度越高,意味着事务之间并发程度越低,执行效率越慢,但是数据的准确性越高。 相反地,隔离程度越低,事务之间并发程度越高,执行效率越高,但是数据的准确性越低。
- 因此,要选择效率还是准确性,要看具体的业务。比如CSDN点赞功能,不需要赞数特别精确,而要做到块,所以可以选择隔离程度低,从而使并发程度高,提高效率;而对于银行业务需要准确性,所以要做到隔离程度高,从而使数据的准确性高。
2、隔离级别
@ (Read uncommitted)=》脏读
例子:
分析:
- 脏读是指事务1在写数据的同时,事务2在读数据,也就是说写的数据还没提交,但是事务2读取到了,就叫做脏读。
- 在场景一中,周老师备课还没完成(相当于提交数据),小明就在一边看到了数据,造成最终小明看到的和课堂上讲的内容不一样。所以造成了脏读。也就是说,写的同时读,并且数据还没提交,可能会造成脏读问题。
- 用read uncommitted 作为隔离条件,会出现脏读问题
- 解决脏读问题的方法,就是在周老师备课的时候,小明不能看,把办公室锁上(手动狗头),也就是周老师完全备课完,小明才能翻看备课本,就是给写"加锁"。即写数据的事务1要把数据提交过后,事务2才能读取数据,就用到更深一层隔离read committed(提交后读)。
@ (Read committed)=》不可重复读
例子:
分析:
- 不可重复读,是事务1在读数据的时候,事务2在修改事务1正在读的数据,事务2提交修改后,事务1看到的数据内容就变了。
- 在场景二中,小明、在读git代码的同时,李老师把代码修改了,造成小明读代码读到一半,代码就改变了。就是说读的同时写,然后写提交数据后,读发生了改变,就是不可重复读问题。
- 以read committed作为隔离等级,会出现不可重复读问题。
- 解决不可重复读的办法,就是小明在读代码时,李老师不能改代码,就可以避免不可重复读的问题,也就是给读加"加锁"。即事务1在读取数据时,事务2不能修改数据,用到的更深一层隔离是Repeatable read(可重复读)。
@ (Repeatable read)=》幻读
分析:
- 幻读,就是事务1在读文件1的同时,因为用来Repeatable read,事务2不能修改文件1,但事务二可以对其它文件操作,比如加个文件2,这就是幻读。
- 在场景二中,用了Repeatable read给读"加锁"后,Java老师李老师不能再修改(操作)小明正在读的文件了,但是李老师还可以操作其它文件,比如添加其他文件,这样小明在读当前Java文件时,会看到多出来一个文件。所以就出现了幻读问题。
- 解决幻读问题方法,除了给当前文件的读和写"加锁",同时文件列表也"加锁"。就可以解决幻读问题了。这就用到了更深一层隔离,Serializable(串行化)
@ (Serializable)
- 进一步解决了幻读问题,但是彻底放弃并发
3、 隔离级别总结
- Read uncommitted,隔离级别最低,会发生脏读、不可重复读、幻读问题。数据准确性低;但是并发程度高,执行效率快
- Read committed,对写"加锁"。隔离级别提高,解决了脏读问题,会发生不可重复读、幻读问题。数据准确性比第一个高,但整体来说准确性还是较低;并发程度比第一个低,效率减慢。
- Repeatable read,对读和写"加锁"。隔离级别进一步提高,解决了脏读,不可重复读问题,会发生幻读问题。准确性较高;并发程度比第二个低,效率进一步减慢。
- Serializable,对读和写"加锁",包括列表所有文件按。隔离级别最高,解决了脏读、不可重复读、幻读问题。彻底舍弃并发,效率最低。
- 在MySQL中,Repeatable read 为默认隔离级别(可修改),也就是解决了脏读、不可重复读,不管幻读问题。