使用 UNION 时,SQL 查询是否保证以原子方式执行?
我发出一个由使用 UNION 分组的多个 SELECT 组成的单个 SQL 查询:
SELECT *
FROM employee
LEFT JOIN department
ON employee.DepartmentID = department.DepartmentID
UNION
SELECT *
FROM employee
RIGHT JOIN department
ON employee.DepartmentID = department.DepartmentID;
假设我在 READ_COMMITTED事务隔离,两个SELECT语句是否保证原子执行?或者我是否面临各个 SELECT 语句之间数据更改的风险? SQL 规范是否讨论了这类事情?
澄清:当我说“原子”时,我并不是指 ACID 中的“A”。我的意思是,我希望部门表和员工表都被读锁定,直到查询完成。
I am issuing a single SQL query consisting of multiple SELECTs grouped using UNION:
SELECT *
FROM employee
LEFT JOIN department
ON employee.DepartmentID = department.DepartmentID
UNION
SELECT *
FROM employee
RIGHT JOIN department
ON employee.DepartmentID = department.DepartmentID;
Assuming I execute this query under READ_COMMITTED transaction isolation, are the two SELECT statements guaranteed to execute atomically? Or do I run the risk of data changing between individual SELECT statements? Does the SQL specification discuss this sort of thing?
CLARIFICATION: When I say "Atomic" I don't mean the "A" in ACID. I mean that I expect both department and employee tables to be read-locked until the query completes.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
是的,该语句是原子的,但数据可以在两次读取之间发生变化。
已提交读
仅保证您不会读取脏数据,它对读取一致性没有任何保证,因为您需要更高的隔离级别。正如您所说,您将接受 SQL Server 示例...
连接 1
(假设在悲观读已提交隔离级别下)
连接 2
现在返回到连接 1
(记住切换回连接 2 以杀死它!)
具体文档涵盖此
已提交
行为在这里Yes the statement is atomic but yes the data can change between the 2 reads.
Read Committed
only guarantees that you don't read dirty data it promises nothing else about consistency of reads for that you would need a higher isolation level.As you said that you would accept a SQL Server Example...
Connection 1
(Assumes under pessimistic read committed isolation level)
Connection 2
Now go back to connection 1
(Remember to switch back to Connection 2 to kill it!)
The specific documentation covering this
READ COMMITED
behaviour is here使用 UNION 将删除可能从任一联合查询返回的任何重复记录,因此不完全是原子的。如果您想要所有联合查询中的所有记录,请使用
UNION ALL
。UNION ALL
也比UNION
快得多。Using
UNION
will remove any duplicate records that may be returned from either of the unioned queries, so not exactly atomic. UseUNION ALL
if you want all records from all unioned queries.UNION ALL
can be much faster thatUNION
also.编辑:请注意,我的答案不正确,但我不想删除它,因为我认为它链接到好问题并有很好的评论。
每笔单独的交易都是原子的。
使用多个子查询的
UNION
是单个 T-SQL 命令、单个事务,并且是原子的。这在一定程度上是避免低效查询(或存储过程)的一个原因,因为它们的原子性质可能会延迟其他事务。
编辑:
有关子查询原子性的更多有趣信息,请参阅此问题
Is update withnested selectatomic操作?
编辑:显然我错了。
这是关于该主题的很好的讨论:SQL Server 2005 中的原子 UPSERT,其中 Remus 提供了一个很好的示例。抱歉怀疑你了,马丁……
EDIT: Note that my answer is incorrect but I do not want to delete it because I think it links to good questions and has good comments.
Every individual transaction is atomic.
A
UNION
using multiple subqueries is a single T-SQL command, a single transaction, and will be atomic.This is, in part, a reason to avoid inefficient queries (or sprocs, for that matter) as their atomic nature can delay other transactions.
EDIT:
Please see this question for more interesting information on atomicity of subqueries
Is update with nested select atomic operation?
EDIT: Apparently I am wrong.
This is a good discussion on the topic: Atomic UPSERT in SQL Server 2005 where Remus poses a good example. Sorry for doubting you, Martin....