面试题答案
一键面试设置事务隔离级别
- 打开MySQL Query Browser:启动MySQL Query Browser,连接到目标数据库。
- 设置事务隔离级别:在查询窗口中执行以下SQL语句来设置事务隔离级别。
- 读未提交(Read Uncommitted):
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
- 读已提交(Read Committed):
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
- 可重复读(Repeatable Read):
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
- 串行化(Serializable):
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
- 读未提交(Read Uncommitted):
不同隔离级别在高并发场景下的优缺点
- 读未提交(Read Uncommitted)
- 优点:允许事务读取未提交的数据,所以不会有锁等待,并发性能很高。
- 缺点:可能会出现脏读,即一个事务读取到另一个事务未提交的数据,数据一致性无法保证。
- 读已提交(Read Committed)
- 优点:避免了脏读,事务只能读取已提交的数据,保证了一定的数据一致性。
- 缺点:可能会出现不可重复读,即在一个事务内多次读取同一数据时,由于其他事务对该数据进行了修改并提交,导致每次读取的结果不同。
- 可重复读(Repeatable Read)
- 优点:避免了脏读和不可重复读,在一个事务内多次读取同一数据时,读取结果保持一致。
- 缺点:可能会出现幻读,即当一个事务按相同条件多次读取数据时,由于其他事务插入了满足条件的新数据,导致每次读取结果集的行数不同。
- 串行化(Serializable)
- 优点:提供了最高级别的数据一致性,完全避免了脏读、不可重复读和幻读问题。
- 缺点:并发性能最差,因为所有事务都是串行执行,会产生大量的锁等待,降低系统的并发处理能力。
处理死锁问题及排查与解决方法
- 死锁检测与自动回滚:MySQL默认开启死锁检测,当检测到死锁时,会自动回滚其中一个事务(通常是代价较小的事务)来打破死锁。
- 排查死锁:
- 查看日志:在MySQL Query Browser中,可以查看MySQL错误日志(通常在MySQL安装目录的data文件夹下的error.log文件),日志中会记录死锁相关的信息,包括涉及的事务、锁等待等情况。
- 使用信息模式表:查询
information_schema.innodb_locks
和information_schema.innodb_lock_waits
表,这两个表记录了当前InnoDB存储引擎中的锁信息和锁等待情况。例如:
SELECT * FROM information_schema.innodb_locks; SELECT * FROM information_schema.innodb_lock_waits;
- 解决死锁:
-
调整事务顺序:分析死锁日志,确定事务获取锁的顺序,调整业务逻辑,使事务以相同的顺序获取锁,避免循环等待。
-
设置合理的锁超时时间:可以通过设置
innodb_lock_wait_timeout
参数来设置锁等待的超时时间,单位为秒。如果一个事务等待锁的时间超过该值,会自动回滚。例如在MySQL配置文件(my.cnf或my.ini)中添加或修改:innodb_lock_wait_timeout = 50
。 -
优化事务逻辑:尽量缩短事务的执行时间,减少锁的持有时间,降低死锁发生的概率。例如将大事务拆分成多个小事务执行。
-