在sql中,带有Select语句的Insert在并发性方面安全吗?

2024-03-27

在我的回答中这个问题 https://stackoverflow.com/questions/1994663/setting-version-column-in-append-only-table/1994757#1994757我建议使用单个插入语句,以及一个增加值的选择,如下所示。

Insert Into VersionTable 
(Id, VersionNumber, Title, Description, ...) 
Select @ObjectId, max(VersionNumber) + 1, @Title, @Description 
From VersionTable 
Where Id = @ObjectId 

我建议这个是因为我believe该语句在并发性方面是安全的,因为如果同时运行同一对象 ID 的另一个插入,则不会有重复的版本号。

我对么?


正如保罗所写:不,这不安全,我想为此添加经验证据:创建一个表Table_1与一个字段ID和一条有价值的记录0。然后执行以下代码同时在两个 Management Studio 查询窗口中:

declare @counter int
set @counter = 0
while @counter < 1000
begin
  set @counter = @counter + 1

  INSERT INTO Table_1
    SELECT MAX(ID) + 1 FROM Table_1 

end

然后执行

SELECT ID, COUNT(*) FROM Table_1 GROUP BY ID HAVING COUNT(*) > 1

在我的 SQL Server 2008 上,一个 ID (662)被创建了两次。因此,应用于单个语句的默认隔离级别是not充足的。


编辑:显然,包装INSERT with BEGIN TRANSACTION and COMMIT不会修复它,因为事务的默认隔离级别仍然是READ COMMITTED,这是不够的。请注意,将事务隔离级别设置为REPEATABLE READ is also不够。实现上述代码的唯一方法safe是添加

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

在顶部。然而,这在我的测试中时不时地造成僵局。

编辑:我发现的唯一安全的解决方案and不产生死锁(至少在我的测试中)是显式地以独占方式锁定表(这里默认事务隔离级别就足够了)。但要小心;这个解决方案可能kill表现:

...loop stuff...
    BEGIN TRANSACTION

    SELECT * FROM Table_1 WITH (TABLOCKX, HOLDLOCK) WHERE 1=0

    INSERT INTO Table_1
      SELECT MAX(ID) + 1 FROM Table_1 

    COMMIT
...loop end...
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在sql中,带有Select语句的Insert在并发性方面安全吗? 的相关文章

  • 插入后用触发器更新多行(sql server)

    我有一个表 orderDetails 包含订单的产品 产品编号 color size quantity 和一个表库存 产品编号 size color stock 订单完成后 我使用此查询将项目插入表中orderDetails INSERT
  • 无法在 SSIS 2012 上使用敏感项目参数

    在 SSIS 2012 中 我尝试对 Oracle 的 OLEDB 连接使用敏感项目参数 它与 Sensitive 属性设置为完美配合FALSE 在项目参数设计器中 但我不希望密码像那样可见 一旦我将敏感属性设置为TRUE并尝试执行我的包
  • 从表中删除孤儿

    我正在尝试清理一张有很多孤立项目的桌子 我通过查找空值来检查是否与另一个表存在关系来解决此问题 DELETE FROM table1 LEFT JOIN table2 ON table1 ID table2 ID WHERE table2
  • 使用 Switch 的报告服务表达式

    我无法让这个表达式与报告服务一起使用 我必须使用 IF 和 ELSE IF 语句 感谢您的任何建议 Switch IsNothing Fields field date Value Fields set flag Value 1 Decli
  • 如何授予所有表的 REFERENCES 权限

    我必须授予REFERENCES登录权限说sql login 我可以给予资助REFERENCES对单个表的权限 例如 GRANT REFERENCES ON Mytable TO sql login 有什么办法可以授予REFERENCES允许
  • 获取家庭成员

    假设以下家庭 其构建架构是 create table PersonConn child int parent int insert into PersonConn values 1 2 insert into PersonConn valu
  • SQL Server 用分隔符分割字符串

    我有一个输入字符串 100 2 3 101 2 1 103 2 3 我想解析它并将其添加到具有 3 列的表中 因此它应该是 f x col1 col2 col3 100 2 3 类似的其他数据以逗号分隔作为记录和 作为列 Thanks ni
  • 如何在SSRS 2012中显示基于总金额的前10名

    我只需要显示前 10 名Class基于Total SUM Premium 柱子 我转到类代码属性组 gt 过滤器并按 SUM Net Written Premium 设置前 10 名 但它不起作用 我只需要显示前 10 名 而且总金额也应该
  • 快速转储 SQL Server 表

    我在 SQL Server 2008 R2 中有一个大表 它包含数十亿行 我需要在我们的应用程序中加载整个数据集 查询全表非常慢 我想使用 bcp 将其转储到文件中并加载它 但问题是字符串列包含各种特殊字符 如 t 0 逗号和 n 我找不到
  • 存储过程和权限 - EXECUTE 就足够了吗?

    我有一个 SQL Server 2008 数据库 其中对基础表的所有访问都是通过存储过程完成的 一些存储过程只是从表中选择记录 而其他存储过程则进行 UPDATE INSERT 和 DELETE 如果存储过程更新表 执行存储过程的用户是否也
  • 列中差异的数量

    我想检索一列每行中有多少个字母的差异 例如 如果您有一个值 test 而另一行有一个值 testing 则 test 和 testing 之间的差异为 4 个字母 该列的数据值为 4 I have reflected about it an
  • 在 Sql Server 中转换为日期时间 MM/dd/yyyy HH:mm:ss

    如何将给定的日期格式转换为MM dd yyyy HH mm ss 我尝试了下面这个但没有实现 谁能帮我 SELECT CONVERT VARCHAR 20 GETDATE 120 SQL Server 2005及以上版本支持 SELECT
  • 在 SQL 数据库中存储“列表”的最正确方法是什么?

    因此 我读了很多关于如何将多个值存储到一个列中是一个坏主意 并且违反了数据标准化的第一条规则 令人惊讶的是 这不是 不要谈论数据标准化 所以我需要一些帮助 目前我正在为我工 作的地方设计一个 ASP NET 网页 我想根据此人所属的 Act
  • 对多个数据库执行 SQL 查询

    我知道我的帖子与该论坛中的其他帖子的标题非常相似 但我真的找不到我需要的答案 这是我的问题 我的 Windows Server 上运行着 SQL Server 在我的 SQL Server 中 我有大约 30 个数据库 它们都具有相同的表和
  • 探查器模板可以迁移到较新版本的 SQL Profiler 吗?

    是否可以将 Profiler 模板迁移到较新版本的 SQL Server 就我而言 我想将 SQL 2008 模板带到 2012 年 我尝试过 1 直接文件复制和 2 导出 导入 在这两种情况下 旧模板都会运行 但无法修改 修改后会出现以下
  • 在文件复制/上传未完成时读取文件内容

    例如 每 5 秒 服务器检查文件是否已添加到特定目录 如果是 它会读取并处理它们 相关文件可能非常大 例如 100 Mo 因此将它们复制 上传到上述目录可能会很长 如果服务器尝试访问尚未完成复制 上传的文件怎么办 JAVA是如何管理这些并发
  • 为什么 SqlClient 在传递 SqlXml 时使用不必要的 XML 转换?

    我有一个关于从 C 代码将 xml 数据类型传递给查询的问题 首先 这是 SQL Server 上的一个表 CREATE TABLE dbo XmlTable id int IDENTITY 1 1 NOT NULL dat xml NOT
  • “RDBMS”附近的语法不正确。当我尝试创建外部数据源时,有人遇到同样的问题吗?

    我使用的是sql server 2017 CREATE EXTERNAL DATA SOURCE MyElasticDBQueryDataSrc WITH TYPE RDBMS LOCATION
  • SQL Server 2014 安装中缺少 SQL Server Integration Services

    我正在尝试使用 Integration Services 安装 SQL Server 2014 Here https www microsoft com en US download details aspx id 42299是我以前用工具
  • 如何在NiFi中映射流文件中的列数据?

    我有 csv 文件 其结构如下 Alfreds Centro Ernst Island Bacchus Germany Mexico Austria UK Canada 01 02 03 04 05 现在我必须将这些数据移入数据库 如下所示

随机推荐