HTML5技术

探讨SQL Server并发处理存在就更新七种解决方案 - Jeffcky

字号+ 作者:H5之家 来源:H5之家 2017-06-01 17:00 我要评论( )

前言 本节我们来讲讲并发中最常见的情况存在即更新,在并发中若未存在行记录则插入,此时未处理好极容易出现插入重复键情况,本文我们来介绍对并发中存在就更新行记录的七种方案并且我们来综合分析最合适的解决方案。 探讨存在就更新七种方案 首先我们来创建

前言

本节我们来讲讲并发中最常见的情况存在即更新,在并发中若未存在行记录则插入,此时未处理好极容易出现插入重复键情况,本文我们来介绍对并发中存在就更新行记录的七种方案并且我们来综合分析最合适的解决方案。

探讨存在就更新七种方案

首先我们来创建测试表

) Test CREATE TABLE Test ( Id int, Name nchar(100), ,primary key (Id), unique (Name) ); GO

解决方案一(开启事务) 

我们统一创建存储过程通过来SQLQueryStress来测试并发情况,我们来看第一种情况。

) TestPro; TestPro ( @Id INT ) ((100)) ( Test WHERE Id = @Id ) UPDATE Test Id = @Id; ELSE INSERT Test ( Id, Name, ) VALUES ( @Id, @Name, 1 ); COMMIT GO

 

同时开启100个线程和200个线程出现插入重复键的几率比较少还是存在。

解决方案二(降低隔离级别为最低隔离级别UNCOMMITED)

) TestPro; TestPro ( @Id INT ) ((100)) ( Test WHERE Id = @Id ) UPDATE Test Id = @Id; ELSE INSERT Test ( Id, Name, ) VALUES ( @Id, @name, 1 ); COMMIT GO

此时问题依旧和解决方案一无异(如果降低级别为最低隔离级别,如果行记录为空,前一事务如果未进行提交,当前事务也能读取到该行记录为空,如果当前事务插入进去并进行提交,此时前一事务再进行提交此时就会出现插入重复键问题)

解决方案三(提升隔离级别为最高级别SERIALIZABLE)

) TestPro; TestPro ( @Id INT ) ((100)) ( dbo.Test WHERE Id = @Id ) UPDATE dbo.Test Id = @Id; ELSE INSERT dbo.Test ( Id, Name, ) VALUES ( @Id, @Name, 1 ); COMMIT GO

在这种情况下更加糟糕,直接到会导致死锁 

 

此时将隔离级别提升为最高隔离级别会解决插入重复键问题,但是对于更新来获取排它锁而未提交,而此时另外一个进程进行查询获取共享锁此时将造成进程间相互阻塞从而造成死锁,所以从此知最高隔离级别有时候能够解决并发问题但是也会带来死锁问题。

解决方案四(提升隔离级别+良好的锁)

此时我们再来在添加最高隔离级别的基础上增添更新锁,如下:

) TestPro; TestPro ( @Id INT ) ((100)) ( dbo.Test WITH(UPDLOCK) WHERE Id = @Id ) UPDATE dbo.Test Id = @Id; ELSE INSERT dbo.Test ( Id, Name, ) VALUES ( @Id, @Name, 1 ); COMMIT GO

 

运行多次均未发现出现什么异常,通过查询数据时使用更新锁而非共享锁,这样的话一来可以读取数据但不阻塞其他事务,二来还确保自上次读取数据后数据未被更改,这样就解决了死锁问题。貌似这样的方案是可行得,如果是高并发不知是否可行。

解决方案五(提升隔离级别为行版本控制SNAPSHOT) 

ALTER DATABASE UpsertTestDatabase UpsertTestDatabase () TestPro; TestPro ( @Id INT ) ((100)) ( dbo.Test WHERE Id = @Id ) UPDATE dbo.Test Id = @Id; ELSE INSERT dbo.Test ( Id, Name, ) VALUES ( @Id, @Name, 1 ); COMMIT GO

上述解决方案也会出现插入重复键问题不可取。

解决方案六(提升隔离级别+表变量)

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 使用sqlserver搭建高可用双机热备的Quartz集群部署【附源码】 - 一线码农

    使用sqlserver搭建高可用双机热备的Quartz集群部署【附源码】 - 一线

    2017-05-29 13:01

  • HTML5支持服务器发送事件(Server-Sent Events)-单向消息传递数据推送(C#示例) - 熊仔其人

    HTML5支持服务器发送事件(Server-Sent Events)-单向消息传递数据推送

    2017-05-19 11:02

  • ASP.NET Core:部署项目到Ubuntu Server - 王杰光

    ASP.NET Core:部署项目到Ubuntu Server - 王杰光

    2017-05-07 18:01

  • EntityFramework Core并发深挖详解,一纸长文,你准备好看完了吗? - Jeffcky

    EntityFramework Core并发深挖详解,一纸长文,你准备好看完了吗? -

    2017-04-05 14:03

网友点评
n