1 事务的特性
? 事务一般是指要做的或者是应做的事情,在计算机中是指访问并可能更新数据库中各种数据项的一个程序执行单元,例如在关系型数据库中,一个事务可以是一条SQL语句或者是一组SQL语句亦或者是整个程序.总之,事务就是一组操作打包在一起,执行的时候能够保证这些操作满足一定的特性,避免出现一旦执行完第一步之后,第二步出现问题了,数据出现错误的现象. ?特性:
- 原子性: 一个事务是一个不可分割的工作单位,要么全部都做了,要么全部都不做(本质上是通过回滚的方式来实现);
- 一致性:事务执行前后,数据处于合法状态;
- 持久性:事务执行完毕之后,事务就被持久修改了(写到磁盘中了);
- 隔离性:多个事务并发执行时,事物之间不能相互干扰,其本质上就是线程安全问题.
需要注意的是隔离性和并发性是相悖的!!
隔离是为了保证数据的准确,并发是为了提高事务执行的效率; 如果多个事务之间的隔离性越强.那么并发程度就越低,效率就越低; 如果多个事务之间隔离性越弱,那么并发程度就越高,效率就越高; 虽然两者之间是相悖的,但是在不同的场景下,对于数据的准确性的要求不一样,可以在满足数据准确要求的前提下尽可能的提高并发程度,也就是说准确和效率我全都要!
2 并发执行时产生的问题
2.1 脏读
? 如果一个事务A正在修改数据,并且还没有提交,另外一个事务B读取了这里修改的内容,此时这样的事务B的读操作就是脏读;因为事务A在提交数据之前,随时可能又要修改刚才的数据.举例说明: 在高等数学期末考试过程中,我的同桌有道题不会做,于是看了我的试卷一眼并记住了答案,但是在我做完左右的题目之后检查了一遍试卷,发现做的不对,于是在交卷之际我将我的同桌不会做的那道题给改了,而这时候我的同桌并不知情,那么我的同桌看到的这个信息就是"脏读". 解决脏读的办法: ?给写操作加锁,例如在我做饭的时候,任何人不能尝我做的饭,只有我做完饭放在桌子上之后才可以吃. 事务A在修改数据的过程中,事务B尝试去读,就会阻塞,并一直阻塞到A提交数据之后,B才能读到数据;引入了写加锁之后,事务的并发程度就降低了,隔离性就提高了! 时间线如下:
2.2 不可重复读
?事务A执行过程中,两次读取到的数据不相同,就是不可重复读.例如还是在高等数学期末考试过程中,有选择题我的同桌不会做,于是在考试之前,我的同桌说你做完选择题给他点一下头,然后我的同桌便可以看,但是在我的同桌看我的选择题的过程中,我又觉得有道题做的不对,我将那道选择题由B改成了A,此时我的同桌就发现刚才这道题选的是B,现在却成了A,这就是不可重复读. 解决办法: ?读也加锁,之前的写加锁指的是我确定选择题答案之前,我的同桌不能看我的试卷内容,但是我的同桌看的时候,我还可以进行修改答案,进行读加锁的意思是我的同桌在看我的选择题的时候,我不能修改答案了,这样就解决了不可重复读的这种情况. ?引入读加锁,事务的并发程度就更低了,效率也更低了,但是隔离性更高了. 时间线如下: 加上读加锁之后:
2.3 幻读
?一次事务执行过程中,多次读取到的结果集不一样,虽然读操作加锁之后,读的时候不能进行修改数据,但是可以新增或者删除数据,那么如何解决幻读呢? 解决方法: ?串行化,让我修改试卷和我的同桌看我的试卷的操作严格串行执行,我改的时候我的同桌不能进行修改,我的同桌看的时候我也不能修改,此时的并发程度最低,效率也最低,但是数据的可靠性是最高的,也就是说必须严格的串行化执行才能解决幻读问题, synchronize 就相当于串行化执行,比较简单粗暴,(不能够更细粒度的优化性能). 时间线如下: 此时我的同桌看到的答案一定是准确的,因为在读锁的限制下,在读的过程中我也无法修改答案,但是我可以删除另外一道选择题(注意不能删除修改的这一道选择题).
3 总结
注意点:
- 此处考虑的并发执行多个事务可以类比成多线程执行一些逻辑,但是此处的写加锁以及读加锁不要和 synchronize 类比;
- 写加锁的意思是: 我在修改试卷得时候,我的同桌不能看我的试卷,但是我的同桌在看我的试卷的时候,我是可以修改试卷的;
- 读加锁的意思就是: 我的同桌在读的时候我也不能写了;
- 同时具备写加锁和读加锁等同于 synchronized.
==MySQL 的隔离级别:==对隔离性的要求具体多高(隔离性高了,并发程度就低了;数据可靠性高了,效率就低了).
- read uncommitted: 允许读取未提交的数据;隔离性最低,并发性最高,会有脏读问题,;
- read committed: 只允许读取已经提交的数据,相当于写加锁;隔离性提高了一些,并发性降低了一些,解决的脏读,但是会有不可重复读;
- repeatable read (MySQL 的默认隔离级别): 给读也加锁;隔离性又提高了一些,并发性又降低了,解决了不可重复读,但是会有幻读问题;
- serializable: 严格串行化执行;隔离性最高,并发性最低,解决了幻读问题.
|