小女巫 发表于 2015-1-16 22:23:14

MSSQL网页设计SQL SERVER悲观锁定和失望锁定利用实例...

在JOIN操作中(需要从多个数据表提取数据时),MySQL只有在主键和外键的数据类型相同时才能使用索引。server<P>在实践的多用户并发会见的临盆情况里边,我们常常要尽量的坚持数据的分歧性。而个中
最典范的例子就是我们从内外边读取数据,反省考证后对数据举行修正,然后写回到数据库
中。在读取和写进的过程当中,假如在多用户并发的情况里边,其他用户已把你要修正的数据
举行了修正长短常有大概产生的情形,如许就形成了数据的纷歧致性。办理如许的举措,SQLSERVER
提出了悲观锁定和失望锁定的观点,下边我以一个实例来讲明怎样利用悲观锁定和失望锁定来
办理如许的成绩。
/*创建测试表:Card,代表一个实在的卡库,供用户注册.用户要从里边选出一个未利用的卡,也就是F_Flag=0的卡,给用户注册:更新F_Name,F_Time,F_Flag字段.假如呈现两个用户同时更新一张卡的情形,是不克不及容忍的,也就是我们所说的数据纷歧致行。*/
createtableCard(F_CardNOvarchar(20),F_Namevarchar(20),F_Flagbit,F_Timedatetime)
Go
insertCard(F_CardNo,F_Flag)select1111-1111,0
insertCard(F_CardNo,F_Flag)select1111-1112,0
insertCard(F_CardNo,F_Flag)select1111-1113,0
insertCard(F_CardNo,F_Flag)select1111-1114,0
insertCard(F_CardNo,F_Flag)select1111-1115,0
insertCard(F_CardNo,F_Flag)select1111-1116,0
insertCard(F_CardNo,F_Flag)select1111-1117,0
insertCard(F_CardNo,F_Flag)select1111-1118,0
insertCard(F_CardNo,F_Flag)select1111-1119,0
insertCard(F_CardNo,F_Flag)select1111-1110,0
Go
--下边是我们常常利用的更新计划以下:

declare@CardNovarchar(20)
BeginTran
--选择一张未利用的卡
selecttop1@CardNo=F_CardNo
fromCardwhereF_Flag=0

--提早50秒,摹拟并发会见.
waitfordelay000:00:50
--把方才选择出来的卡举行注册.
updateCard
setF_Name=user,
F_Time=getdate(),
F_Flag=1
whereF_CardNo=@CardNo
commit
成绩:假如我们在统一窗口实行统一段代码,可是往失落了waitfordelay子句.双方实行终了后我们发明只管实行了两次注册,可是只注册了一张卡,也就是两团体注册了统一张卡.
失望锁定办理计划
--我们只需对上边的代码做巨大的改动就能够完成失望的锁定.
declare@CardNovarchar(20)
BeginTran
--选择一张未利用的卡
selecttop1@CardNo=F_CardNo
fromCardwith(UPDLOCK)whereF_Flag=0

--提早50秒,摹拟并发会见.
waitfordelay000:00:50
--把方才选择出来的卡举行注册.
updateCard
setF_Name=user,
F_Time=getdate(),
F_Flag=1
whereF_CardNo=@CardNo
commit
注重个中的区分了吗?with(updlock),是的,我们在查询的时分利用了with(UPDLOCK)选项,在查询纪录的时分我们就对纪录加上了更新锁,暗示我们行将对次纪录举行更新.注重更新锁和共享锁是不抵触的,也就是其他用户还能够查询此表的内容,可是和更新锁和排它锁是抵触的.以是其他的更新用户就会堵塞.假如我们在别的一个窗口实行此代码,一样不加waifordelay子句.双方实行终了后,我们发明乐成的注册了两张卡.大概我们已发明了失望锁定的弱点:当一个用户举行更新的事件的时分,其他更新用户必需列队守候,即便谁人用户更新的不是统一笔记录.
悲观锁定办理计划
--起首我们在Card内外边加上一列F_TimeStamp列,该列是varbinary(8)范例.可是在更新的时分这个值会主动增加.
altertableCardaddF_TimeStamptimestampnotnull

--失望锁定
declare@CardNovarchar(20)
declare@timestampvarbinary(8)
declare@rowcountint
BeginTran
--获得卡号和原始的工夫戳值
selecttop1@CardNo=F_CardNo,
@timestamp=F_TimeStamp
fromCard
whereF_Flag=0

--提早50秒,摹拟并发会见.
waitfordelay000:00:50
--注册卡,可是要对照工夫戳是不是产生了变更.假如没有产生变更.更新乐成.假如产生变更,更新失利.
updateCard
setF_Name=user,
F_Time=getdate(),
F_Flag=1
whereF_CardNo=@CardNoandF_TimeStamp=@timestamp
set@rowcount=@@rowcount
if@rowcount=1
begin
print更新乐成!
commit
end
elseif@rowcount=0
begin
ifexists(select1fromCardwhereF_CardNo=@CardNo)
begin
print此卡已被别的一个用户注册!
rollbacktran
end
else
begin
print其实不存在此卡!
rollbacktran
end
end
在别的一个窗口里边实行没有waitfor的代码,注册乐成后,前往本来的窗口,我们就会发明到工夫后它显现的提醒是此卡以被别的一个用户注册的提醒.很分明,如许我们也能够制止两个用户同时注册一张卡的征象的呈现.同时,利用这类办法的别的一个优点是没有利用更新锁,如许增添的体系的并发处置才能.
上边我具体先容了悲观锁定和失望锁定的利用办法,在实践临盆情况里边,假如并发量不年夜,我们完整可使用失望锁定的办法,由于这类办法利用起来十分便利和复杂.可是假如体系的并发十分年夜的话,失望锁定会带来十分年夜的功能成绩,以是我们就要选择悲观锁定的办法.
假如人人发明文章里边有甚么毛病的中央,请实时提示我,也接待有乐趣的一同研讨会商.

Cluster/NDB高冗余的存储引擎,用多台数据机器联合提供服务以提高整体性能和安全性。适合数据量大,安全和性能要求高的应用

admin 发表于 2015-1-19 10:03:47

可能有的朋友会抱怨集成的orderby,其实如果使用ranking函数,Orderby是少不了的。如果担心Orderby会影响效率,可以为orderby的字段建立聚集索引,查询计划会忽略orderby操作(因为本来就是排序的嘛)。

冷月葬花魂 发表于 2015-1-28 06:05:26

如果是将来做数据库的开发设计,就应该详细学习T-SQL的各种细节,包括T-SQL的程序设计、存储过程、触发器以及具体使用某个开发语言来访问数据库。

小妖女 发表于 2015-2-5 18:51:49

索引视图2k就有。但是2005对其效率作了一些改进但是schema.viewname的作用域真是太限制了它的应用面。还有一大堆的环境参数和种种限制都让人对它有点却步。

精灵巫婆 发表于 2015-2-13 06:43:52

我们学到了什么?思考问题的时候从表的角度来思考问

谁可相欹 发表于 2015-3-3 18:21:59

SQL语言是学习所有数据库产品的基础,无论你是做数据库管理还是做数据库开发都是这样。不过具体学习的侧重点要看你将来做哪一块,如果是做数据库管理(DBA),侧重点应该放在SQLServer的系统管理上.

若相依 发表于 2015-3-11 12:42:18

我们学到了什么?思考问题的时候从表的角度来思考问

小魔女 发表于 2015-3-18 18:45:45

多加的系统视图和实时系统信息这些东西对DBA挑优非常有帮助,但是感觉粒度还是不太细。

老尸 发表于 2015-3-26 14:17:37

如果是将来做数据库的开发设计,就应该详细学习T-SQL的各种细节,包括T-SQL的程序设计、存储过程、触发器以及具体使用某个开发语言来访问数据库。
页: [1]
查看完整版本: MSSQL网页设计SQL SERVER悲观锁定和失望锁定利用实例...