事务的隔离级别:
事务的基本特性:
在可重复读隔离级别下可能会产生脏写/丢失更新的问题。如下:
事务A首先进行查询,并在java代码中对查询结果进行一些运算,还未执行后续的更新操作,事务还未提交。这时候事务B执行了update操作并提交事务。然后事务A再执行update 表名 set 字段名=java代码运算后的结果 where 。。。
这样就就会事务B执行的更新操作给覆盖掉,也就是脏写问题。
解决方法:
update 表名 set 字段名=字段名+100 where 。。。。。
在可重复读隔离级别下,开启事务后,第一次select时,我们可以理解为这个时候当前事务保存了整个数据库的一个快照(当然底层不是使用快照 实际上是使用mvcc对进行更新操作后的各行数据都维护了版本链)。在这个事务中,即使其他数据表被其他事务更新了,我们在这个事务中读取的还是之前的数据。
在可重复读隔离界别下,有人说解决了幻读问题,有人说没有解决幻读问题。其实在可重复读隔离级别下没有完全解决幻读问题。
幻读:在一次事务中,第二次select操作读取到了其他事务新插入的数据。
原因是:在可重复读隔离级别下,select是快照读,更新操作是使用数据库中最新的数据做的更新。更新完成后再查询这条数据查询的结果也是最新的数据。但也仅仅只是这一行数据,其他数据读取的还是第一次select时的数据。
所以就会造成:在一个事务中,如果我们不对其他事务新增的数据做更新操作,在整个事务中我们是查询不到其他事务新增的数据,这也就是有些人说解决了幻读问题的原因。如果在一个事务中我们对其他事务新增的数据进行更新操作,我们这时再select是能查询出来其他事务新增的这条数据,这也就是没有完全解决幻读问题。
在串行化隔离界别下,就是以前我们学习读锁,写锁的思想了,在执行sql语句时会自动加上共享锁或者是排他锁,并造成读写互斥。但是其他三种隔离界别在select时不会加共享锁,仅仅是串行化隔离界别会加。
我们在使用InnoDB存储引擎时,在update时,它为什么是持久化Redo log文件到磁盘,而不是直接把脏页刷新写回磁盘。原因是因为Redo log是磁盘顺序写,效率要高。
大事务/长事务的影响:
事务优化: