执行 2 个 SQL 命令而不在其间执行其他命令的正确方法

Posted

技术标签:

【中文标题】执行 2 个 SQL 命令而不在其间执行其他命令的正确方法【英文标题】:Correct way to execute 2 SQL commands without other command executing in between 【发布时间】:2013-04-15 13:38:09 【问题描述】:

建议的副本没有回答标题中的问题。

我想在没有任何其他“用户”(我不确定正确的术语)在它们之间执行命令的情况下执行两个 MSSQL 命令。

搜索,我发现了两种似乎可以实现但不确定的方法:

    使用制表符。 - 但我已经看到它被认为是不好的做法。

    使用事务 - 但我只能找到它是原子的, 而不必锁定其他操作。

正确的方法是什么?

更多信息:只有我的程序将访问数据库,但它可能来自它的多个实例,我不介意短暂等待 - 如果一个实例必须排队等待一两秒 -没关系。

编辑:我正在尝试插入一行并获取其标识。 (这似乎不像我期望的那样简单。)

【问题讨论】:

您能解释一下为什么中间不会执行其他查询如此重要吗? 这两个命令是什么? 事务不会锁定正在使用的表以防止更改使用的数据吗? @Pako 插入一行并获取其标识。 (这似乎不像我期望的那样简单。) @MAV 这将是我问题的一部分。会吗? 【参考方案1】:

要插入一行并获取其标识,您无需阻止所有其他命令。只需将事务与SCOPE_IDENTITY 结合使用即可:

BEGIN TRAN;

INSERT INTO MyTable (MyColumn)
VALUES ('MyValue');

SELECT SCOPE_IDENTITY();

COMMIT TRAN;

更多关于SCOPE_IDENTITYMSDN的信息。

【讨论】:

我错过了获取插入值的 ID,这是针对特定场景的方法。 谢谢。作为阅读您的答案的结果,我进行了搜索,发现 MSSQL 中可能存在一个错误,这使得它不可靠。 (见:support.microsoft.com/kb/2019779)。还是那是旧的但已经修复了? 根据该链接,“此问题的修复首先在 SQL Server 2008 R2 Service Pack 1 的累积更新 5 中发布。” 再次感谢。总而言之 - 事务不允许任何其他命令进入事务的命令之间。这是真的吗? 这实际上是一个复杂的问题,取决于Isolation Levels。但一般来说,事务将锁定您要插入的表,并且不允许对该表 执行任何其他命令。但是,它仍然允许不影响该特定表的命令——这是一件好事。【参考方案2】:

您需要使用带有IsolationLevel 或Serializable 的事务。这将防止其他用户在事务期间读取或修改查询使用的行,而不会完全锁定表。

【讨论】:

谢谢。我想要锁定整个表。这可能吗? @ispiro 你到底为什么要锁定整个表? 这样在没有先看到这些数据的情况下,没有人会向它写入新数据。 这种方法会给你带来痛苦的世界......你应该做的是尽可能数量的锁定,如果你依赖约束需要确保多个用户不能和一个记录实际上与另一个记录相同。例如,如果您有一个包含用户详细信息的表,那么在电子邮件地址列上添加唯一约束比尝试锁定表以防止其他用户在插入记录时对其进行读取或写入要容易得多。【参考方案3】:

您不能阻止 commands 在其他两个命令之间执行。您所能做的就是防止数据被修改,直到您自己完成修改为止。这是通过使用相应隔离级别的事务来完成的。

【讨论】:

以上是关于执行 2 个 SQL 命令而不在其间执行其他命令的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

Redis 源码学习之 Redis 事务Nosql

如何在批处理文件中执行多个 git 命令而不在第一个命令之后终止?

pl/sql里面命令窗口和sql窗口区别是啥?

如何执行一个mysql的sql脚本文件

BAT/CMD中将命令执行结果赋值给变量

使用 ORACLE PL/SQL 执行 Unix Sun Solaris 命令的权限问题