日期:2014-05-18  浏览次数:20580 次

高手进!关于waitfor delay时锁定记录的问题!还有IIS连数据库失败时候的问题!
第一个大问题:
这是关于sql中的延迟一段时间函数
waitfor delay 时间 的问题!
首先,我用存储过程执行这个函数
CREATE PROCEDURE [winclose] 
@session_id nvarchar(15)=null
AS
WAITFOR DELAY '00:00:02'
if exists(select * from user_online WITH (NOLOCK) where session_id=@session_id and refing='yes'and window=0)
begin 
delete from user_online where session_id=@session_id 

我执行这句话的意图,是延迟2秒后查询是否存在refing字段='yes'and window字段为0
如果存在,删除这一行记录!
如果在这wait的2秒内,有其他操作能改变这一记录的refing或者window字段值,让其不符合其删除条件,那么就不执行删除。
问题是,在wait这2秒内,如果有其他操作真的想改变refing或者window字段值,那么系统的dllhost.exe进程CPU占用就会变得狂高,并且挣扎了老长一段时间,改变refing或者window字段值并不成功。
结果是2秒内,就算有改变字段值的操作,都会无效,导致存储过程直接删除这行记录!
我又换成触发器来执行
CREATE TRIGGER [deluser] ON [dbo].[user_online] 
after UPDATE
AS
declare @username nvarchar(15)
select @username=username from user_online
where username in
(select username from user_online WITH (NOLOCK)  
where refing='yes'and window=0)
waitfor delay '00:00:03'
if exists(select * from user_online WITH (NOLOCK) where username=@username and refing='yes'and window=0)
begin
delete from user_online where username=@username
insert into message (username,touser_name,msg,rndid,color,usertype) values ('system','all',@username+'has gone','system','black','service')
end
如果这段嫌累可以不看,意图差不多。
结果还是一样!CPU占用100%,缓下来后直接删除了这行记录!我在学校的服务器cpu( Xeon 5410 2.33G)上尝试了一下也会出现这情况!不是我机器配置的问题!
请问高手们:WAITFOR DELAY语句执行的时候,难道锁定表记录?但我尝试把单个的WAITFOR DELAY 20秒 执行,然后用其他的查询语句执行这个表的加,删,都成功!!?只有执行上面的存储过程或触发器才会出现这个情况?到底这是怎么回事?
第二个问题,关于IIS的:只要asp连接SQLserver数据库语句出错,比如说本来select*from a1不小心写成select*from a2,而这a2表不存在在库中,那么就CPU100%,服务器上一样!根本不报错!其他任何错误,比如连接帐号,密码错了,也是100%,根本没有了提示!请问这时为什么?


------解决方案--------------------
未见你说的问题一:
SQL code
create table user_online(session_id nvarchar(15),refing varchar(10),window int)
insert into user_online select 'abc','yes',0
union all select 'def','yes',0
union all select 'hij','no',0
go

CREATE PROCEDURE [winclose] 
@session_id  nvarchar(15)=null 
AS 
WAITFOR DELAY '00:02:00' 
if exists(select * from  user_online  WITH (NOLOCK)  where session_id=@session_id and refing='yes'and window=0) 
begin 
delete from user_online  where session_id=@session_id
end
go

------解决方案--------------------
探讨
回11楼。。
我将那个关闭窗口就执行
判断refing=yes,window=0删除行记录的存储过程加成延迟20秒,然后把打开窗口的存储过程用Javascript延迟1秒后再请求执行refing=no,window+1的存储过程(不是用数据库的delay而是用前台函数推迟1秒后执行)
这样看理论上并不算同一个批处理吧?可是还是直接删除了,不管打开页面时候的存储过程。。或者说这存储过程被直接推迟到关闭窗口的存储过程执行完后再执行。。。好奇怪啊。。。百…

------解决方案--------------------
探讨
我把3个相关存储过程贴出来吧你看看!
无论怎么样,只要执行那个delay就无法在delay的时间段内改变它的列值!
这是关闭窗口时执行的window减1,refing为yes:

SQL code
CREATE PROCEDURE [setref]
@session_id nvarchar(15)=null
AS
update user_online set window=window-1,refing='yes' where session_id=@session_id
GO



这是关闭页面后执行的delay。检测20秒后的字段refing和window值。注意,只是20秒!…

------解决方案--------------------
学习 顶