【发布时间】:2011-04-22 04:13:55
【问题描述】:
我有一个user 表,字段为lastusedecnumber。
我需要访问并增加lastusedecnumber。
在访问期间,我需要锁定特定的用户行(而不是整个表)。
我该怎么做?
表格类型为MyISAM。
【问题讨论】:
我有一个user 表,字段为lastusedecnumber。
我需要访问并增加lastusedecnumber。
在访问期间,我需要锁定特定的用户行(而不是整个表)。
我该怎么做?
表格类型为MyISAM。
【问题讨论】:
我不想从 myisam 转换我的整个数据库。所以我只是尝试创建一个基于我要锁定的记录的 id 命名的新表。如果创建表成功,做我的工作并在最后删除表。建表不成功,停止。
【讨论】:
MySQL 仅使用来自 MyISAM 表的表级锁定。如果可以,请切换到 InnoDB 进行行级锁定。
这里是 MySQL 站点的链接,该站点描述了由 SQL 语句为 InnoDB 表设置的锁。 http://dev.mysql.com/doc/refman/5.0/en/innodb-locks-set.html
【讨论】:
有点晚了,但希望对某人有所帮助:
UPDATE user SET lastusedecnumber = LAST_INSERT_ID(lastusedecnumber + 1);
SELECT LAST_INSERT_ID();
将为您提供 lastusedecnumber 的原子增量,并能够使用 SELECT LAST_INSERT_ID() 读取 lastusedecnumber 字段的新值(增量后)。
【讨论】:
更好的解决方法是创建一个包含时间戳的列。每当您想锁定行时,您都会将其更新为当前时间。将更新解锁到过去至少 x 分钟的时间。然后检查它是否被锁定,检查时间戳是否至少 x 分钟。
这样,如果进程崩溃(或用户从未完成他们的操作),锁会在 x 分钟后有效地过期。
【讨论】:
作为一种解决方法,您可以在表中添加一列,例如 locked TINYINT(1) - 每当您想要锁定该行时,您将其设置为 1。当您现在尝试访问此行时,您要做的第一件事是检查是否设置了 locked 字段。
要解锁该行,只需再次将其设置为0。不好,但一个非常简单的解决方法。
【讨论】:
LOCK=0,那么它们都进入了临界区,both 都设置了 LOCK=1,并且您有一个隐藏的竞争条件错误。