事务是啥
MySQL的事务就是把多个sql语句操作打包在一起执行,要么全部执行,要么一个都别执行。这种操作称为“原子性”,是事务最核心的特征。当某个sql操作出错时,就会进行“回滚/rollback”操作,即把执行过的操作逆向恢复回去,数据库会把每个操作记录下来,当某个操作出错时,就会把之前的操作进行逆操作,比如前面是删除操作,逆操作就进行插入操作,把删除的数据重新插入回去。
start transaction;--开启事务
--
--中间写多个sql
--
commit;--提交事务
当开启事务后不会立即执行sql操作,会等到commit提交事务后,会统一执行多个sql。
事务的四大特性
-
原子性:即把多个sql操作合并在一起(相当于一个操作),统一执行,要么都执行成功,要么一个都别执行。
-
一致性:即事务执行前后,数据都是合法的。
-
持久性:即事务的操作后的结果都会写入硬盘,无论是程序还是主机重启,修改操作都是生效的。
-
隔离性:即同一个数据库服务器,在针对多个事务并发执行时,事务之间相互影响的程度。隔离性越高,并发程度越低,执行效率越慢,反之隔离性越低,并发越高,效率越快。隔离性分为四个档位,分别是:
read uncommited 读未提交
:这个档位MySQL不做任何限制,隔离性最低,并发程度最高,执行效率最快,此时存在“脏读、不可重复读、幻读”问题。像博客文章点赞数量这种操作就可以使用这个档位,因为不管点赞是重复了还是没点赞成功,问题都不大,效率快就行。read commited 读已提交
:这个档位是针对“写操作”加锁,此时隔离性提高,并发程度降低,执行效率降低,此时解决了”脏读“问题,存在”不可重复读、幻读“问题。repeatable read 可重复读
:Mysql的默认档位,此时针对“写操作”和“读操作”都进行加锁,此时隔离性进一步提高,并发程度进一步降低,此时解决了“脏读、不可重复读”,依旧存在“幻读”问题。serializable 串行化
:这个档位是严格执行串行化的,即放弃并发,隔离性最高,执行效率最慢,解决了“脏读、不可重复读、幻读”问题。
脏读:即一个事务读了一个脏数据,比如此时有两个事务针对同一份数据进行操作。事务B正在修改文件内容还未提交,同时事务A正在读文件,当事务A读完之后走了,事务B此时才修改完数据并且提交了,于是导致事务A之前读到的数据就变成了无效数据,这种情况就称为“脏读”,于是可以进行”写操作“加锁,即在“写操作”时,事务A不能读数据。
不可重复读:即针对”写操作“进行加锁的情况下,依旧是两个事务针对同一份数据进行操作,在事务B针对这份数据进行”写操作“时,事务A是不能进行”写操作”的,但是可以读这份文件。于是事务A在读同一份数据时,事务B随即修改了数据,导致事务A读了一半发现数据变了,这种情况就称为“不可重复读”问题,即同一个事务针对一份文件连续读两次的结果不一致,于是需要针对”读操作“进行加锁。
幻读:在“写操作”和“读操作”都进行加锁的情况下,事务A进行读数据(文件)时,事务B不能针对同一份文件进行“读写”操作,不过事务B可以针对其他文件进行操作,比如增加一个文件,或者删除一个文件,于是当事务A读完一个文件后,发现文件的数量变了,这种情况就称为“幻读”问题。即同一个事务连续两次读的结果集不同,于是需要严格执行串行化,即放弃并发。
栗子:
【脏读】比如学校黑板报,同学A早上10点来看黑板报发现自己考试成绩第一名,高兴的回到寝室;此时学生B正在写黑板报,写到最后发现漏了一名同学的成绩,此时同学A真实排名是第三名,不过同学A依旧以为自己是第一名,这种情况就属于是“脏读问题”。【不可重复读】同学A在读第一块黑板报,同学B紧接把黑板报的内容改了,导致同学A此时发现读的内容已经变了,这种情况就属于是”不可重复读“,不可重复读是同学A能立马发现内容变了,而脏读是同学A不能发现内容变了。【幻读】同学A此时在读黑板报,目前只有一个黑板报有内容,当同学A读完这个黑板报后就应该算是读完了黑板报,但是当同学A读完之后,发现旁边几块黑板报被同学B都写上了内容,此时导致同学A发现不再是只有一块黑板报有内容,而是有好几块,这种情况就是“幻读”。