MySQL InnoDB分布式系统中如何避免读取已排他锁定的数据行?
解决分布式系统中InnoDB表批量锁定读取唯一数据行的问题
我在分布式系统环境下,需要操作MySQL(InnoDB)的EMPLOYEE表,表结构包含:
internal_employee_id:自增主键external_employee_idnamegenderexported:布尔类型字段
核心需求是:集群内多个进程每次读取exported = false的前100条唯一数据行,并且读取的行在处理期间保持锁定,确保进程1读取1-100行后,进程2无法看到这些行,只能读取下一批可用的100行。
最初的尝试及问题
一开始我使用了悲观写锁(FOR UPDATE),Java代码如下:
Query query = entityManager.createNativeQuery("select * from employee " + "where exported = 0 limit 100 for update"); List<Employee> employeeListLocked = query.getResultList();
但这个方案没达到预期效果:虽然能阻止多进程同时更新这些行,但无法阻止其他进程读取到同一批已被锁定的数据行,导致多个进程拿到重复的数据集。
最终解决方案:使用SKIP LOCKED特性
后来发现InnoDB的SKIP LOCKED特性正好能解决这个问题,它会让数据库引擎在执行查询时自动跳过已经被锁定的数据行,只返回当前可用的未锁定行。更新后的Java代码如下:
Query query = entityManager.createNativeQuery("select * from employee " + "where exported = 0 limit 100 for update skip locked"); List<Employee> employeeListLocked = query.getResultList();
这样一来,每个进程都会拿到完全不重复的未锁定数据行,完美满足了分布式环境下的批量唯一读取并锁定的需求。
内容的提问来源于stack exchange,提问作者Murtaza Hasan
相关产品推荐
相关产品推荐

