有这样的一个应用:
SQL SERVER 2005
客户提交一个处理请求,放在请求表QQB里作为一条记录,等待被取出处理,处理程序在取出该记录处理时将其zt字段设为“正在处理”;如果该记录超时1分钟未被处理程序取出处理,另一个监控程序会将该条记录删除。问题是这样的,我担心监控程序的删除操作和处理程序的取出处理并更新操作会同时发生,在被删除的同时却又被取出处理,请问如下的操作会出现这样的情况吗?为了绝对避免这种情况出现,应该如何写程序?请高手指教,写出出具体的操作代码。请求表QQB,三个字段:
xh int
tjsj datetime 请求提交时间
zt varchar(50) 记录处理的状态,未被处理时为null,取出处理时其值为“正在处理”处理程序:
......
update qqb set zt='正在处理' where xh=@xh
监控程序:
declare @tjsj datetime,@zt varchar(50)
select @tjsj=tjsj,@zt=zt where xh=@xh
if datediff(n,@tjsj,getdate())>1 and (zt is null)
delete qqb where xh=@xh
SQL SERVER 2005
客户提交一个处理请求,放在请求表QQB里作为一条记录,等待被取出处理,处理程序在取出该记录处理时将其zt字段设为“正在处理”;如果该记录超时1分钟未被处理程序取出处理,另一个监控程序会将该条记录删除。问题是这样的,我担心监控程序的删除操作和处理程序的取出处理并更新操作会同时发生,在被删除的同时却又被取出处理,请问如下的操作会出现这样的情况吗?为了绝对避免这种情况出现,应该如何写程序?请高手指教,写出出具体的操作代码。请求表QQB,三个字段:
xh int
tjsj datetime 请求提交时间
zt varchar(50) 记录处理的状态,未被处理时为null,取出处理时其值为“正在处理”处理程序:
......
update qqb set zt='正在处理' where xh=@xh
监控程序:
declare @tjsj datetime,@zt varchar(50)
select @tjsj=tjsj,@zt=zt where xh=@xh
if datediff(n,@tjsj,getdate())>1 and (zt is null)
delete qqb where xh=@xh
update qqb set zt='正在处理' where xh=@xh
if @@rowcount = 0 return这样就可以保证只能被其中之一处理。
1 如何锁一个表的某一行A 连接中执行SET TRANSACTION ISOLATION LEVEL REPEATABLE READbegin transelect * from tablename with (rowlock) where id=3waitfor delay '00:00:05'commit tranB连接中如果执行update tablename set colname='10' where id=3 --则要等待5秒update tablename set colname='10' where id<>3 --可立即执行2 锁定数据库的一个表SELECT * FROM table WITH (HOLDLOCK)
注意: 锁定数据库的一个表的区别SELECT * FROM table WITH (HOLDLOCK)
其他事务可以读取表,但不能更新删除SELECT * FROM table WITH (TABLOCKX)
其他事务不能读取表,更新和删除
update qqb set zt='正在处理' where xh=@xh
if @@rowcount = 0 return
......--修改监控程序,改成如下两种形式都可以:
--1)加事务
declare @tjsj datetime,@zt varchar(50)
begin tran
select @tjsj=tjsj,@zt=zt from qqb where xh=@xh
if datediff(n,@tjsj,getdate())>1 and (zt is null)
delete qqb where xh=@xh
commit tran--2)压缩成一条语句
delete qqb where xh=@xh and zt is null and datediff(n,tjsj,getdate()) > 1这样就可以绝对保证只能被其中之一处理。