面试题答案
一键面试记录锁使用场景
- 并发写入操作:当多个事务同时尝试向同一表中插入或更新具有唯一约束(如主键、唯一索引)的记录时,使用记录锁可以防止数据冲突。例如,在用户注册场景中,若用户名设为唯一索引,当多个用户同时注册相同用户名时,记录锁可确保只有一个注册成功。
- 并发读取与写入:在读取数据并根据读取结果进行写入操作的场景下,记录锁用于保证读取的数据在写入操作完成前不被其他事务修改。比如银行转账,从账户A向账户B转账,先读取账户A余额,在更新账户A余额和账户B余额的过程中,需要锁定账户A的记录,防止其他事务在该过程中修改账户A余额。
- 事务隔离级别为可重复读(RR):在RR隔离级别下,MySQL默认使用记录锁来保证同一事务内多次读取同一记录的结果一致。例如,在一个事务内多次查询某个订单状态,若期间有其他事务尝试修改该订单状态,记录锁可阻止其修改,保证当前事务内查询结果的一致性。
记录锁实现锁定特定记录保证数据一致性的原理
- 基于索引:MySQL的记录锁是基于索引实现的。当对某条记录加锁时,会先定位到该记录对应的索引项。例如,如果是基于主键索引加锁,MySQL会快速通过主键值定位到对应的索引记录。若表中没有合适的索引,MySQL可能会进行全表扫描,这会大大降低锁的效率且可能导致锁争用加剧。
- 锁的类型:记录锁分为共享锁(S锁)和排他锁(X锁)。共享锁允许事务读取记录,多个事务可以同时持有同一记录的共享锁;排他锁则阻止其他事务对记录进行任何读或写操作。当一个事务获取了某记录的排他锁时,其他事务必须等待该排他锁释放后才能获取对该记录的锁。
- 加锁过程:以更新操作为例,假设事务T1要更新表中某条记录R,首先会根据记录R的主键或相关索引定位到对应的索引项。然后,事务T1会请求对该索引项加排他锁。如果此时没有其他事务持有该索引项的锁,那么事务T1将成功获取排他锁,接着就可以安全地更新记录R。在此期间,若有其他事务T2尝试读取或更新记录R,由于事务T1持有排他锁,事务T2会被阻塞,直到事务T1提交或回滚释放锁。
- 锁的释放:当事务完成(提交或回滚)时,记录锁会被释放。这样其他等待的事务就有机会获取锁并对记录进行操作,从而在并发环境下保证了数据的一致性。