在使用UNION时,SQL查询是否保证以原子方式执行?

在使用UNION时,SQL查询是否保证以原子方式执行?,sql,transactions,Sql,Transactions,我将发出一个SQL查询,该查询由使用UNION分组的多个选择组成: SELECT * FROM employee LEFT JOIN department ON employee.DepartmentID = department.DepartmentID UNION SELECT * FROM employee RIGHT JOIN department ON employee.DepartmentID = dep

我将发出一个SQL查询,该查询由使用UNION分组的多个选择组成:

SELECT *
FROM   employee 
       LEFT JOIN department 
          ON employee.DepartmentID = department.DepartmentID
UNION
SELECT *
FROM   employee
       RIGHT JOIN department
          ON employee.DepartmentID = department.DepartmentID;
假设我在事务隔离下执行此查询,那么这两个SELECT语句是否保证以原子方式执行?或者,我是否有在单个SELECT语句之间更改数据的风险?SQL规范讨论过这类事情吗


澄清:当我说“原子”时,我不是指酸中的“A”。我的意思是,我希望在查询完成之前,department表和employee表都会被读取锁定。

使用
UNION
将删除任何可能从任何一个UNION查询返回的重复记录,因此不完全是原子的。如果需要所有联合查询中的所有记录,请使用
UNION ALL
UNION ALL
UNION
快得多。

编辑:注意我的答案不正确,但我不想删除它,因为我认为它链接到了好的问题,并且有好的评论。

每个事务都是原子的

使用多个子查询的
UNION
是单个T-SQL命令、单个事务,并且是原子的

这在一定程度上是避免低效查询(或存储过程)的一个原因,因为它们的原子性质可能会延迟其他事务

编辑: 有关子查询原子性的更多有趣信息,请参见此问题

编辑:显然我错了。


这是一个很好的话题讨论:雷姆斯在哪里是一个很好的例子。很抱歉怀疑您,Martin….

是的,该语句是原子语句,但是的,数据可以在两次读取之间更改

readcommitted
只保证您不读取脏数据,它不保证读取的一致性,因为您需要更高的隔离级别

正如您所说,您将接受SQL Server示例

连接1 (假设处于悲观读取提交隔离级别)

现在回到连接1

name                                               DepartmentID
-------------------------------------------------- ------------
bill                                               1
bob                                                1
(记住切换回连接2以终止它!)

涵盖此
的特定文档已提交

共享锁类型决定何时使用 它将被发布。行锁是 在下一行之前释放 处理。页面锁被释放 当阅读下一页时,和表 当语句 完成


为什么不使用完全联接?@dlev:我使用的数据库(H2)不支持完全联接。
UNION ALL
速度明显更快,但在这种情况下,在其中一个联接中,您需要一个条件来过滤掉
内部联接
记录,否则它们将被复制。问题主要是正确性,不是表演。我正在尝试执行完全外部联接,但我的数据库(H2)不支持它。@Matthew:当READ_COMMITTED允许不可重复的读取时,你怎么能说“每个事务都是原子的”?@Gili读取锁适用于整个事务。。。我不知道您是否可以明确地为子查询声明其他内容(尽管这对我来说似乎很危险)@MatthewPK-我不知道有关
H2
的任何信息,但是对于SQL Server Underread,提交的隔离级别共享锁会在读取页面后立即释放。自联接etc完全有可能拥有同一行的两个不同版本。@Martin,这可能是真的,但下一个读入队列将是事务中的下一个子查询。因此,除非某个嵌套查询导致行的作用域发生更改,否则我不希望它发生更改。您能链接到支持您所说内容的官方文档/规范吗?@Martin在这种情况下,存储过程如何被视为原子的?@Martin:如果我理解正确,每个选择都保证以原子方式执行,但总体查询并非如此。如果语句的子部分不能保证彼此一致,那么你怎么能说语句是原子的呢?@Gili-我的意思是它们将满足
ACID
中的
A
<代码>隔离
level@Martin:我澄清了这个问题。当我写“atomic”时,我不是指Acid中的A。@Gili-我可以确认,在SQL Server中,在悲观的
read committed
隔离级别下,绝对没有这样的保证,您需要不同的隔离级别来实现这一点。我可能很快就会删除这个答案,因为我对H2或SQL标准对此一无所知!
while (1=1)
UPDATE employee SET name = CASE WHEN name = 'bob' THEN 'bill' else 'bob' END
name                                               DepartmentID
-------------------------------------------------- ------------
bill                                               1
bob                                                1