sql-server – 选择/插入版本的Upsert:是否有高并发的设计模式
发布时间:2020-12-12 07:49:20 所属栏目:MsSql教程 来源:网络整理
导读:我想做一个UPSERT的SELECT / INSERT版本.以下是现有代码的模板: // CREATE TABLE Table (RowID INT NOT NULL IDENTITY(1,1),RowValue VARCHAR(50))IF NOT EXISTS (SELECT * FROM Table WHERE RowValue = @VALUE)BEGIN INSERT Table VALUES (@Value) SELECT @
我想做一个UPSERT的SELECT / INSERT版本.以下是现有代码的模板:
// CREATE TABLE Table (RowID INT NOT NULL IDENTITY(1,1),RowValue VARCHAR(50)) IF NOT EXISTS (SELECT * FROM Table WHERE RowValue = @VALUE) BEGIN INSERT Table VALUES (@Value) SELECT @id = SCOPEIDENTITY() END ELSE SELECT @id = RowID FROM Table WHERE RowValue = @VALUE) 该查询将从许多并发会话中调用.我的性能测试表明,它将一直在特定负载下抛出主键违规. 是否有一个高并发方法,这个查询将允许它保持性能,同时仍然避免插入已经存在的数据? 解决方法您可以使用LOCKs来实现SERIALIZABLE,但这会降低并发性.为什么不先尝试共同的条件(“大多是插入或大部分选择”),然后安全处理“补救”行动?也就是说,“JFDI”模式…预计大多数INSERT(球场70-80%): 只是尝试插入.如果失败,行已经创建.不需要担心并发,因为TRY / CATCH处理重复. BEGIN TRY INSERT Table VALUES (@Value) SELECT @id = SCOPEIDENTITY() END TRY BEGIN CATCH IF ERROR_NUMBER() <> 2627 RAISERROR etc ELSE -- only error was a dupe insert so must already have a row to select SELECT @id = RowID FROM Table WHERE RowValue = @VALUE END CATCH 主要选择: 类似的,但是尝试先获取数据.没有数据=需要INSERT.再次,如果两个并发调用尝试插入,因为它们都发现该行缺少TRY / CATCH句柄. BEGIN TRY SELECT @id = RowID FROM Table WHERE RowValue = @VALUE IF @@ROWCOUNT = 0 BEGIN INSERT Table VALUES (@Value) SELECT @id = SCOPEIDENTITY() END END TRY BEGIN CATCH IF ERROR_NUMBER() <> 2627 RAISERROR etc ELSE SELECT @id = RowID FROM Table WHERE RowValue = @VALUE END CATCH 第二个似乎重复,但它是高度并发的.锁将实现相同但以并发为代价… 编辑: 为什么不使用MERGE? 如果使用OUTPUT子句,它将只返回更新的内容.所以你需要一个虚拟UPDATE来为OUTPUT子句生成INSERTED表.如果您必须使用许多调用(由OP隐含)进行虚拟更新,那么这是很多日志写入才能够使用MERGE. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- 解决:SQLServer 2000 Driver for JDBC]Error establishing
- sql-server – SQL Server 2008 R2错误:15023,用户,组或角
- SQLServer(MSSQL)、MySQL、SQLite、Access相互迁移转换工具
- SQL Server 某年第一周开始日期实现方法
- SQLSERVER 根据值查询表名
- SQLSERVER快速有条件删除海量数据
- sql – 如何将逗号分隔列转换为db2中的多个行
- SQLSERVER2008 维护计划
- sql-server – 对于asp.net mvc Web应用程序,哪种方法可以将
- sqlserver中去除字符串中连续的分隔符的sql语句