• 并发事务之间相互干扰,可能导致事务出现读脏,不可重复度,幻读等问题
• InnoDB实现了SQL92标准中的四种隔离级别
(1)读未提交:select不加锁,可能出现读脏;
(2)读提交(RC):普通select快照读,锁select /update /delete 会使用记录锁,可能出现不可重复读;
(3)可重复读(RR):普通select快照读,锁select /update /delete 根据查询条件情况,会选择记录锁,或者间隙锁/临键锁,以防止读取到幻影记录;
(4)串行化:select隐式转化为select ... in share mode,会被update与delete互斥;
• InnoDB默认的隔离级别是RR,用得最多的隔离级别是RC
事务的隔离级别是数据库管理系统确保数据一致性的重要机制,它解决了并发事务执行时可能出现的问题,如读脏、不可重复读和幻读。在SQL92标准中,定义了四种事务隔离级别,分别是读未提交(Read Uncommitted)、读提交(Read Committed,简称RC)、可重复读(Repeated Read,简称RR)以及串行化(Serializable)。InnoDB存储引擎实现了这四种隔离级别,每种级别通过不同的锁定策略来保障数据的一致性和并发性。
1. 读未提交(Read Uncommitted)
在这个级别下,事务可以读取到其他事务未提交的数据,即存在“读脏”的风险。这是因为没有进行任何锁定,允许最高的并发性,但一致性最弱。在InnoDB中,`SELECT`语句不会加锁,可能导致读取到不稳定的数据。
2. 读提交(Read Committed,RC)
在RC级别,事务只能看到已经提交的数据,避免了“读脏”问题,但仍然可能出现“不可重复读”。InnoDB在RC级别下,普通的`SELECT`执行快照读,不加锁;而`SELECT ... FOR UPDATE`或`SELECT ... IN SHARE MODE`、`UPDATE`、`DELETE`等操作会使用记录锁,阻止其他事务修改已锁定的记录。这样能防止读取到未提交的修改,但无法防止在两次查询之间插入的新记录。
3. 可重复读(Repeated Read,RR)
RR是InnoDB的默认隔离级别,它解决了“不可重复读”问题。在RR级别,普通`SELECT`采用快照读,不加锁,利用多版本并发控制(MVCC)保证一致性。对于`SELECT ... FOR UPDATE`、`SELECT ... IN SHARE MODE`、`UPDATE`、`DELETE`,InnoDB会根据查询条件选择记录锁、间隙锁(Gap Lock)或临键锁(Next-Key Lock),防止在当前事务的两次查询间插入导致幻读。但是,由于使用了锁定,可能会降低并发性能。
4. 串行化(Serializable)
最高的隔离级别,所有`SELECT`语句都会被转换为`SELECT ... IN SHARE MODE`,这会导致在有未提交修改的行上的读操作被阻塞,以确保事务的串行执行,从而完全避免并发问题。然而,这也牺牲了并发性,只在非常需要绝对一致性的场景下使用。
在实际应用中,互联网大数据量、高并发的场景通常倾向于选择读提交(RC)或可重复读(RR)隔离级别,因为它们在保证数据一致性的同时,提供了较好的并发性能。串行化隔离级别虽然提供最强的一致性,但由于其低并发性,一般只在特殊需求下使用。读未提交(Read Uncommitted)隔离级别由于其一致性问题,通常不被推荐用于生产环境。