mysql并发和自动递增密钥

a9wyjsp7  于 2021-06-19  发布在  Mysql
关注(0)|答案(1)|浏览(319)

我有一个mysql用户表和一个由用户执行的操作表(通过主键userid链接到该用户)。actions表有一个递增键indx。每当我向该表中添加新行时,我就会用刚刚添加到actions表中的行的indx更新相关users行的最新列。比如:

INSERT INTO actions(indx,actionname,userid) VALUES(default, "myaction", 1);
UPDATE users SET latest=LAST_INSERT_ID() WHERE userid=1;

我可以通过查看最新更新是否高于上次检查时的更新来检查用户的更新。
我的问题是,如果在数据库上打开了多个连接,并且他们同时尝试为同一个用户添加操作,connection2可能会在connection1的insert和update之间运行insert和update,并且他们试图更新的用户的最新条目将不再具有最新操作条目的indx。
我一直在阅读事务、隔离级别等方面的内容,但还没有找到解决这个问题的方法(尽管我对这些工作原理的理解非常不稳定,所以可能我只是误解了)。我想我需要一种方法来锁定actions表,直到用户表被更新。这个应用程序最多只能被几百个用户使用,所以我认为暂时锁定表所带来的性能损失不会太大。
那么,这是mysql中可以实现的功能吗?有更好的解决办法吗?我想这种通用模式一定很常见:一个表有一堆不同的行,第二个表有一行跟踪表a中每个不同行的元数据,并且每次第一个表被更改时都需要进行原子更新。所以我希望有一个不太复杂的解决方案

pb3s4cty

pb3s4cty1#

使用选择。。。要更新以锁定行以序列化对表的访问并防止争用条件,请执行以下操作:

START TRANSACTION;
SELECT any_column FROM users WHERE userid=1 FOR UPDATE;
INSERT INTO actions(indx,actionname,userid) VALUES(default, "myaction", 1);
UPDATE users SET latest=LATEST_INSERT_ID() WHERE userid=1;
COMMIT;

但是,这会降低插入速率,因为所有会话中的所有事务都将被序列化。
更好的选择是不将最后一个id存储在 users 一张table也没有。只是使用 SELECT max( id ) FROM actions WHERE userid = x 在所有需要这个号码的地方。带索引的 actions( userid ) 这个查询将非常快(假设 id 列是此表中的主键),插入不会减慢

相关问题