为什么要用数据库锁
写了这么久的程序一直没用到过数据库锁,最近才开始关心这个事,以下为个人理解请大侠们批评指正
看如下sql代码
1 --为什么要用数据库锁
2 alter proc ProcDeleteStock
3 @stoc_id int,
4 @commandMessage nvarchar(50) out
5 as
6 set @commandMessage='执行成功'
7 begin tran
8 declare @Exist int --记录是否存在
9 declare @StockSate int --订单状态,0未审核,1已审核
10 declare @StockDetailCount int --订单明细数量
11 select @Exist=0
12 set @StockSate=0
13 set @StockDetailCount=0
14 select @StockSate=stoc_sate,@Exist=stoc_id from tab_Stock where stoc_id = @stoc_id
15 select @StockDetailCount=COUNT(stoc_Id) from tab_StockDetail where stoc_id=@stoc_id --订单id为@stoc_id 的订单明细数量
16 if(@Exist = 0)
17 set @commandMessage='订单不存在'
18 else if(@StockSate = 1)
19 set @commandMessage='订单已审核无法删除'
20 else if(@StockDetailCount <> 0)
21 set @commandMessage='请先删除该订单的所有明细'
22 else
23 delete tab_Stock where stoc_id = @stoc_id
24 if(@@ERROR<>0)
25 begin
26 set @commandMessage=@@ERROR --for debug
27 rollback tran
28 end
29 else
30 commit tran
31
32 declare @errorMessage nvarchar(50)
33 exec ProcDeleteStock 4,@errorMessage out
34 print @errorMessage
执行以上存储过程
1 declare @errorMessage nvarchar(50)
2 exec ProcDeleteStock x,@errorMessage out
3 print @errorMessage
单独就这段代码没有问题,如果在执行完存储过程第15行后并且在存储过程提交前并发以下任何一行代码结果会怎么样呢?
1. update tab_Stock set stoc_sate=1 where stoc_id=x2. insert into tab_StockDetail(stoc_id,*,*) values(x,n,n)
因此我们要用到数据库锁,修改存储过程的14,15行如下:
1 select @StockSate=stoc_sate,@Exist=stoc_id from tab_Stock with(updLock) where stoc_id = @stoc_id
2 select @StockDetailCount=COUNT(stoc_Id) from tab_StockDetail with(updLock) where stoc_id=@stoc_id --订单id为@stoc_id 的订单明细数量
这样在存储过程ProcDeleteStock 中的事物提交之前
1 update tab_Stock set stoc_sate=1 where stoc_id=x
2 insert into tab_StockDetail(stoc_id,*,*) values(x,n,n)
不会执行成功。