gpt4 book ai didi

mysql - MySQL Query 是否包含子查询原子?

转载 作者:IT王子 更新时间:2023-10-28 23:52:34 24 4
gpt4 key购买 nike

有两个表:

表 1 独特 session

ID    Count 

表 2( session )

ID    Name

只有当 name 不存在于 session 中时,我才想更新 count 以计算唯一 session ,这是一个示例,因此目标不是通过其他方式进行,但问题是:

Rowsaffected = Update table1 
set Count = Count + 1
where (Select count(*) from table2 where Name = 'user1' ) = 0;

Insert into table2 (NAME) values('user');

first query 是原子查询吗?如果是,则没有问题。

如果不是,那么如果有多个线程运行来执行上述操作怎么办?有可能:

线程 1:count 返回 0,它在线程 2 启动之前更新了表 1 但没有更新表 2。线程 2:它找到计数 0,它也将更新计数。

现在对于同一个用户,计数是 2,这是不应该发生的。

任何建议/反馈。

最佳答案

最好使用 exists 子句: https://dev.mysql.com/doc/refman/8.0/en/exists-and-not-exists-subqueries.html

Rowsaffected = Update table1 set Count = Count + 1 where NOT EXISTS (Select ID from table2 where Name = 'user1' );

仅针对您问题的原子部分的引用,但可以肯定的是,您可以将这两个语句包装在一个事务中。虽然根据您的并发模型,您可能希望考虑提高事务隔离级别,但这看起来并不是绝对必要的。

MySQL 将语句视为原子 https://dev.mysql.com/doc/refman/8.0/en/mysql-acid.html

从技术上讲,子查询是它们出现的语句的一部分。 https://dev.mysql.com/doc/refman/8.0/en/expressions.html尽管在语法上类似于独立语句,但它们是单独运行的 - 优化器将整个语句视为一个工作单元。

这确实假设您正在使用支持事务的存储引擎: https://dev.mysql.com/doc/refman/8.0/en/storage-engines.html(在页面底部的表格末尾)

隔离级别要求在查询运行时获取的读锁将一直保留,直到获取了写锁并且所有锁将一起释放。 https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html

(尽管文档似乎没有明确说明这一点,否则它无法保证隔离级别)

关于mysql - MySQL Query 是否包含子查询原子?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5816062/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com