msql中事务的五个属性
1 原子性
一个事务是一个不可分割的工作单位,要木全都做了,要木全都不做了
2 一致性
事物执行前后,数据处于合法状态
3 持久性
事物执行完毕后,数据就被持久修改(写到磁盘中了)
4 隔离性
多个事物并发执行的时候,事物之间不能相互干扰
- 隔离性和并发是相悖的
- 隔离是为了保证数据的准确
- 并发是为了提高事务执行的效率,如果多个事务之间隔离性越强,并发程度越低,效率就越低;如果多个事务之间的隔离性越弱,并发程度越高,效率就越低。
- 我们为了满足数据准确要求的前提下就要尽可能的提高效率
而在隔离性不强的情况下会产生三个情况
- 脏读,我们用将事务A比作老师,事务B比作学生,老师在写字写了uzb,学生看见了记上了笔记本,但是老师发现他写错了,老师改成了uzi,但是学生已经记下了。简单来说一个事务A在写数据的时候,但还未提交,事务B读了过去,但是A发现它写错了,立即改了(事务A在提交之前会随时修改数据)然后再提交。
如何解决脏读:加锁,假如老师在写字的时候,没写完的时候不许记笔记,然后大家就在等老师写完,老师写完之后再说可以记了,然后大家再记。就无法产生脏读了,相当于给事务A的写加锁,但是引入写加锁的时候,事务B读的时候就无法并发执行了。降低了效率,并发性变弱,隔离性更强。 - 不可重复读,老师写完了字,学生开始读了,但是在学生读的时候,老师又开始写了,写的时候又将uzi修改成changzhang,卧槽,学生记完笔记后的时候又发现没uzi了,变成了changzha
ng,就很气。
为了解决这个问题,我们引入了读加锁,就是在老师在学生们读的时候不可以往黑板上写笔记或者修改笔记。但是引入读加锁后,事务的并发程度就更低了,效率也就更低了,隔离性更强。 - 幻读同一个事务中,两次读到的结果集不一致,虽然读加锁后,读的时候不能修改,但是可以新增和删除记录,也就是在学生读的时候老师不能改变uzi,但是可以把uzi删掉,变成空白。或者直接加入一个changzhang,变成了uzi ,changzhang。不能修改,但老师可以删除和增添。为解决这个问题,可以严格串行化执行,才可以解决幻读问题。
也就是根据MySQl上述的三个问题,我们将MySQL的隔离级别分为四个
- read uncommitted:允许读取未提交的数据(有脏读问题)
- read committed:只允许读取已经提交的数据,相当于写加锁(但是有不可重复读问题)
- repeatable read:MySQL的默认隔离级别解决了不可重复读问题,但是有幻读问题
- serializable:严格的串行化执行,解决了幻读问题
SQL语句中显可以示指定当前SQl中使用那种级别,不指定的话默认为repeatable read