最近在维护Web Service接口时,由于数据数据量达到千万级别,接口调用不时出现错误让人不胜烦恼,经过性能测试查出瓶颈在数据库数据处理上,可着实忙了一番。相信众多程序猿和DBA都会头痛性能的问题,尤其是应用程序池的超时和假死造成的后台数据处理中断,带来的数据维护带来不小的麻烦。

在此背景下追查后台处理数据时请求中断成为目前棘手的问题,被吊打之余正努力想办法解决根本问题,小弟在解决防止数据处理时请求中断上,想到了Transaction的可行性,于是有了这篇随笔出来,废话比较多,下面开始吧

首先做点准备工作,建库建表

create database tranTest
go use TranTest
go create table TranTest(
ID int identity (1,1),
CreateTime datetime,
Value int
)
go

带transaction的 Proc ,不才sql小学级别,将就着看,大意是1秒钟插一条记录到TranTest表中,持续30秒

create proc [dbo].[testTrans]
as
begin
declare @timeSpan datetime
declare @timeStart datetime
declare @val int = 1
begin try
begin transaction
set @timeSpan = GETDATE();set @timeStart=getdate();
while(DATEDIFF(second,@timeStart,getdate())<=30)
begin
while(DATEDIFF(SECOND,@timeSpan,getdate())=1)
begin
set @timeSpan = GETDATE()
insert into TranTest values (getdate(),@val);
--update trantest set value=@val,createtime=getdate() where id=(select max(id) from trantest)
--set @val = @val +1
end
end
commit transaction
end try
begin catch
select ERROR_NUMBER() as errornumber
rollback transaction
end catch
end

有了材料咱开始吧,首先要验证是transaction默认Level设置,在中断时的锁是行锁还是表锁

场景设置: 先运行3秒,强制中断,查询表中的数据,查看锁情况

exec  testTrans  走起,执行3秒强制结束查询分析器的执行

查看数据及锁的情况,带脏读查看表数据如下,3秒钟插入了3条,由于强制中止了执行,造成5条锁数据,其中重点关注id为54的锁(database级锁本文不做扩展),此时不带脏读是查不出数据的(去掉with(nolock)),由于只有3条数据都被加锁,无法确定是否为

上表使用的sql如下,新开查询分析页使用exec ('kill 54')解除锁,再来查询表数据,会发现表中没有数据,此时sql server回滚了数据操作

select * from TranTest with(nolock)

SELECT request_session_id sessionid,
resource_type type,
resource_database_id dbid,
OBJECT_NAME(resource_associated_entity_id, resource_database_id) objectname,
request_mode rmode,
request_status rstatus
FROM sys.dm_tran_locks
WHERE resource_type IN ('DATABASE', 'OBJECT') 解除锁
exec ('kill 54')

修改下Proc中的30,将30改为3运行到结束,先正常插入3条数据为后面测试做准备。再将proc更新成如下代码,单独修改单条数据

alter proc [dbo].[testTrans]
as
begin
declare @timeSpan datetime
declare @timeStart datetime
declare @val int = 1
begin try
begin transaction
set @timeSpan = GETDATE();set @timeStart=getdate();
while(DATEDIFF(second,@timeStart,getdate())<=30)
begin
while(DATEDIFF(SECOND,@timeSpan,getdate())=1)
begin
set @timeSpan = GETDATE()
--insert into TranTest values (getdate(),@val);
update trantest set value=@val,createtime=getdate() where id=(select max(id) from trantest)
set @val = @val +1
end
end
commit transaction
end try
begin catch
select ERROR_NUMBER() as errornumber
rollback transaction
end catch
end

运行更新后的proc,3秒时强制终止执行,看下表值的前后变化,依然新开查询分析页,查询表中的值

我们使用脏读方式看到了ID为3的数据被更新了,再来看看锁的情况,此时的锁默认为行锁,验证方法很简单,使用select * from TranTest查询时查询被hang住了,使用select * from TranTest where id=1 时,数据就出来了,如果将 where 的条件改成 id=3查询依然无法返回,此时说明ID=3的这条数据被锁

下面继续看看回滚方面的验证,上图已经查到行锁ID为54,使用exec('kill 54')解除行锁, 再来查看表数据,ID=3的数据恢复到初始状态,回滚被执行了

有小伙伴可能会问,IIS的应用程序池连接中断和查询分析器强制终止是相同行为吗,要验证很简单,建一个空网站,调用上面的proc,设置执行超时时间为3秒,行为与查询分析器中一样,大家可以去验证一下,关于锁的Level问题和Database级的锁后面继续探索

浅谈SQL Transaction在请求中断后的行锁表锁的更多相关文章

  1. 浅谈SQL Server、MySQL中char,varchar,nchar,nvarchar区别

    最近一次的面试中,被面试官问到varchar和nvarchar的区别,脑海里记得是定长和可变长度的区别,但却没能说出来.后来,在网上找了下网友总结的区别.在这里做个备忘录: 一,SQL Server中 ...

  2. c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程

    c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...

  3. 转【】浅谈sql中的in与not in,exists与not exists的区别_

    浅谈sql中的in与not in,exists与not exists的区别   1.in和exists in是把外表和内表作hash连接,而exists是对外表作loop循环,每次loop循环再对内表 ...

  4. 浅谈sql中的in与not in,exists与not exists的区别

    转 浅谈sql中的in与not in,exists与not exists的区别   12月12日北京OSC源创会 —— 开源技术的年终盛典 »   sql exists in 1.in和exists ...

  5. 【sql注入】浅谈sql注入中的Post注入

    [sql注入]浅谈sql注入中的Post注入 本文来源:i春秋学院 00x01在许多交流群中,我看见很多朋友对于post注入很是迷茫,曾几何,我也是这样,因为我们都被复杂化了,想的太辅助了所以导致现在 ...

  6. 浅谈SQL注入风险 - 一个Login拿下Server

    前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...

  7. 浅谈SQL注入风险 - 一个Login拿下Server(转)

    前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...

  8. 【SqlServer系列】浅谈SQL Server事务与锁(上篇)

    一  概述 在数据库方面,对于非DBA的程序员来说,事务与锁是一大难点,针对该难点,本篇文章视图采用图文的方式来与大家一起探讨. “浅谈SQL Server 事务与锁”这个专题共分两篇,上篇主讲事务及 ...

  9. 浅谈SQL Server内部运行机制

    对于已经很熟悉T-SQL的读者,或者对于较专业的DBA来说,逻辑的增删改查,或者较复杂的SQL语句,都是非常简单的,不存在任何挑战,不值得一提,那么,SQL的哪些方面是他们的挑战 或者软肋呢? 那就是 ...

随机推荐

  1. Gcc的Makefile简单使用

    Gcc的Makefile简单使用http://blog.chinaunix.net/uid-9330295-id-2425867.html

  2. EndNote(三)之中文引文导入方式

    上一篇文章讲了Web of Science,PubMed的引文如何导入到EndNote中.这次,写一下常用的中文文献查找网站的引文如何导入EndNote. 本人常用的中文文献查找网站,主要是知网(CN ...

  3. Unity3D 解决用Unity导出的Android工程在6.0及以上设备会弹出一串权限对话框的问题

    解决用Unity导出的Android工程在6.0及以上设备会弹出一串权限对话框的问题 <meta-data android:name="unityplayer.SkipPermissi ...

  4. js_面向对象

    面向对象的语言有一个标志,即拥有类的概念,抽象实例对象的公共属性与方法,基于类可以创建任意多个实例对象,一般具有封装.继承.多态的特性!但JS中对象与纯面向对象语言中的对象是不同的,ECMA标准定义J ...

  5. JSP复习整理(五)JavaBean使用表单处理数据

    一.先建立用户输入的数据 usingGetparameter.html <!DOCTYPE html> <html> <head> <meta charset ...

  6. ofbiz定时任务配置

    1.一个service的java类 2.在framework/service/servicedef/service.xml中配置上一步的service服务. <service name=&quo ...

  7. sql中NVARCHAR(MAX) 性能和占空间分析 varchar(n),nvarchar(n) 长度性能及所占空间分析

    varchar(n),nvarchar(n) 中的n怎么解释: nvarchar(n)最多能存n个字符,不区分中英文. varchar(n)最多能存n个字节,一个中文是两个字节. 所占空间: nvar ...

  8. python关于分割与拼接的那些事

    1.split分割 基于re模块和正则表达式对象的方法split(),以后再做学习 基于字符串的split()方法 :字符串对象的split()方法也只能处理非常简单的情况,而且不支持多个分隔符,对分 ...

  9. 使用dd命令备份Linux分区

    为了备份分区,开始使用的是Remastersys,但最终生成的iso文件仅有几十K,应该是软件bug,且此软件不再更新,后尝试使用Linux Respin,但github一直连接不上. 其实可以尝试使 ...

  10. haproxy+keepalived

    global_defs { router_id LVS_DEVEL } vrrp_script chk_haproxy { script "killall -0 haproxy" ...