我应该使用MySQL锁表还是有更好的解决方案?

0 投票
1 回答
560 浏览
提问于 2025-04-18 15:35

我正在开发一个多进程的应用程序,每个进程有时会执行以下代码:

db_cursor.execute("SELECT MAX(id) FROM prqueue;")

for record in db_cursor.fetchall():
    if record[0]:
        db_cursor.execute("DELETE FROM prqueue WHERE id='%s'" % record[0]);
        db_connector.commit()

我遇到了一个问题:可能会出现两条进程同时获取到相同的最大值,然后它们都试图删除这个值。这样的情况在我的应用程序中是不可接受的,因为每个值只能被一个进程获取(和删除)。

我该如何解决这个问题?在获取最大值和删除时,是否必须对表进行锁定,还是有其他更好的方法可以做到这一点?

谢谢。

1 个回答

2

考虑使用 GET_LOCK() 来模拟记录锁。

选择一个特定的名字来进行锁定,比如 'prqueue_max_del'

调用 SELECT GET_LOCK('prqueue_max_del',30) 来锁定这个名字 'prqueue_max_del'。如果这个名字可以被锁定,它会返回 1,并设置锁;如果在 30 秒内锁定失败,它会返回 0(第二个参数是超时时间)。

完成后,使用 SELECT RELEASE_LOCK('prqueue_max_del') 来释放锁。

在每个事务中,你必须使用相同的名字,如果在一个事务中再次调用 GET_LOCK(),之前设置的锁会被释放。

要注意;因为只有这个抽象的名字被锁定,所以所有不使用这个方法和名字的其他进程仍然可以独立地访问你的表。

GET_LOCK() 文档

撰写回答