transaction.md
数据库的事务隔离级别有哪些? 事务的四大特性有哪些?
Q:讲一下事务,以及哪个隔离级别解决了脏读和幻读
A:事务是指一组作为单一逻辑单元执行的数据库操作,要么全部成功提交,要么全部失败回滚,其包含 ACID 四大特性,也就是原子性、一致性、隔离性和持久性,原子性是指事务中的操作要么都执行,要么都不执行,一致性是指事务执行前后数据库的状态是一致的,隔离性是指并发执行的事务之间互不干扰,一个事务不应该看到另一个未提交事务的中间状态,持久性是指事务一旦提交,对数据的修改就是永久性的,即使数据库崩溃也不会丢失;常见的并发事务间出现的问题主要有脏读、不可重复读和幻读,脏读是指一个事务在修改了数据之后还未提交事务时,另一个事务却读取到了该事务修改后的数据,如果该事务触发回滚,那么这个数据就是过期的,不可重复读是指一个事务读取了两次同一个字段的数据,但另一个事务却在该事务读取两次数据的中间修改了一次这个字段的数据并且在该事务提交之前就提交了,这就导致这个事务发现前后两次读到的数据不一样,幻读是指当一个事务多次查询某个条件的记录时,另一个事务对符合条件的记录数量做了修改,比如插入或者删除了一条记录,并在这个事务提交前提交了,导致该事务多次的查询结果记录数量不一致,可能增加了也可能减少了,就像出现了幻觉一样;为了解决脏读、不可重复读和幻读的问题,事务有不同的隔离级别,分别是读未提交、读已提交、可重复读和串行化,读未提交是最低的隔离级别,相当于什么都没做,读已提交很好地解决了脏读的问题,它强调当一个事务提交之后,这个事务做的变更才能被其他事务看到,它在每条语句执行前都会重新生成一个 read view,也就是一个数据快照,而可重复读则是在启动事务时生成数据快照,然后整个事务期间都用这一个 read view,所以可重复读可以很好地避免不可重复读的问题,而幻读只有使用最高的隔离级别串行化才能彻底解决,串行化是在内部对查询范围和索引都加了锁,保证任何并发插入和删除都要排队;在 MySQL 中 InnoDB 引擎默认的隔离级别是可重复读,但它对幻读也做了优化,可以避免大多数幻读,它主要是用记录锁和间隙锁实现的,来阻塞某个范围内其他的插入语句