2

我打算编写以下查询:

INSERT INTO summary (user_id, total_points, count_operations)
SELECT 
   15 AS user_id,
   (SELECT SUM(points) FROM operations WHERE user_id = 15) AS total_points,
   (SELECT COUNT(*) FROM operations WHERE user_id = 15) AS count_operations
ON DUPLICATE KEY UPDATE
total_points = VALUES(total_points), 
count_operations = VALUES(count_operations);

整个语句是原子的吗?即 MySQL(使用 MyISAM 引擎)是否在内部锁定了operations表?

MySQL 是否有可能顺序执行两个子查询,这可能会导致在某些情况下(如果在该时间范围内添加新操作)total_pointsandcount_operations会不一致?

4

1 回答 1

1

MyISAM 仍然使用表级锁

这些存储引擎通过始终在查询开始时一次请求所有需要的锁并始终以相同的顺序锁定表来避免死锁。权衡是这种策略降低了并发性;其他想要修改表的会话必须等到当前 DML 语句完成。

因此,其他想要更新您正在使用的表的进程必须等到您的事务完成。如果它对表“操作”设置读锁,所有后续的写锁都会进入队列并等待。

于 2012-12-02T19:18:28.503 回答