求助多个用户同时调用同一个存储过程

dsa88885555 2015-07-09 03:17:22
假设有下面的存储过程
ALTER PROCEDURE [dbo].[p_DelteSales]
@Office_Code nvarchar(20),
@Invoice_No nvarchar(20),
@InvoiceLine_No nvarchar(80) ,
@finalAccept_No nvarchar(20) output
AS

BEGIN
declare @procductCD nvarchar(20)
declare @saleQTY nvarchar(20)

--获取产品cd,数量
select @procductCD=procductcode,@saleQTY=saleQTY
from dbo.T_Sales
where SaleCode=@Invoice_No
and SaleBrCode =@InvoiceLine_No

---库存更新
update dbo.T_INV
set 数量 = isnull(数量,0)+@saleQTY,
where 仓库CD=@Office_Code
and procductcode=@procductCD

--dbo.T_Sales数据删除
delete dbo.T_Sales
where SaleCode=@Invoice_No
and SaleBrCode =@InvoiceLine_No

set @finalAccept_No='1'
END

这时候 同时有用户A和B 对这个存储过程进行调用,会出现这种情况吗?
A先执行之后得到了一个procductCD和@saleQTY 然后后面的库存更新还没执行的时候
B开始调用存储过程,得到了另一个procductCD和@saleQTY 然后A在执行库存更新的时候使用了B得到的那个数据呢?

或者A先执行之后得到了一个procductCD和@saleQTY 然后后面的库存更新还没执行的时候
B开始调用存储过程,导致A后面的存储过程不执行呢?



如果有这些问题的话,这个存储过程要如何修改呢。
...全文
795 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
dsa88885555 2015-07-10
  • 打赏
  • 举报
回复
引用 8 楼 rfq 的回复:
1、您的存储过程很容易产生丢失更新 2、建议 可以 添加 应用程序锁 exec sp_getapplock 'ProcLock','Exclusive','session' exec 实际的存储过程 exec sp_releaseapplock 'ProcLock','session 3、或者 在 存储过程 添加事物 然后 在 在取数 表中添加 表排他锁 with (tablockx)
我sql基本不会啊,就只会一些简单的增删改查。。。能耐具体说下吗。。是不是像我在7楼那样加的啊
rfq 2015-07-10
  • 打赏
  • 举报
回复
1、您的存储过程很容易产生丢失更新 2、建议 可以 添加 应用程序锁 exec sp_getapplock 'ProcLock','Exclusive','session' exec 实际的存储过程 exec sp_releaseapplock 'ProcLock','session 3、或者 在 存储过程 添加事物 然后 在 在取数 表中添加 表排他锁 with (tablockx)
dsa88885555 2015-07-10
  • 打赏
  • 举报
回复
引用 4 楼 Cherise_huang 的回复:
可以让多个用户同时调用同一个存储过程时依次执行,而不是同时执行 可以使用事务和锁来操作 有一种叫应用程序锁的锁也许能满足你的需要 您可以通过sp_getapplock 来获得特定的锁,以锁定该过程,当该过程完成后,可以使用sp_releaseapplock;来释放锁 exec sp_getapplock 'ProcLock','Exclusive','session' exec 实际的存储过程 exec sp_releaseapplock 'ProcLock','session' http://www.cnblogs.com/wenjl520/archive/2012/08/24/2654412.html
是不是 ALTER PROCEDURE [dbo].[p_DelteSales] @Office_Code nvarchar(20), @Invoice_No nvarchar(20), @InvoiceLine_No nvarchar(80) , @finalAccept_No nvarchar(20) output AS BEGIN exec sp_getapplock 'ProcLock','Exclusive','session' declare @procductCD nvarchar(20) declare @saleQTY nvarchar(20) --获取产品cd,数量 select @procductCD=procductcode,@saleQTY=saleQTY from dbo.T_Sales where SaleCode=@Invoice_No and SaleBrCode =@InvoiceLine_No ---库存更新 update dbo.T_INV set 数量 = isnull(数量,0)+@saleQTY, where 仓库CD=@Office_Code and procductcode=@procductCD --dbo.T_Sales数据删除 delete dbo.T_Sales where SaleCode=@Invoice_No and SaleBrCode =@InvoiceLine_No set @finalAccept_No='1' exec sp_releaseapplock 'ProcLock','session' END 就这样加呢
dsa88885555 2015-07-10
  • 打赏
  • 举报
回复
存储过程前加这个有用吗? WITH RECOMPILE 让他每次重新生成新的执行计划
wtujedp 2015-07-09
  • 打赏
  • 举报
回复
引用 3 楼 dsa88885555 的回复:
[quote=引用 2 楼 shoppo0505 的回复:] 调用时 锁资源 begin tran end tran
不好意思,不懂啥意思[/quote] SQL Server 事务语法   事务全部是关于原子性的。原子性的概念是指可以把一些事情当做一个单元来看待。从数据库的角度看,它是指应全部执行或全部都不执行的一条或多条语句的最小组合。 为了理解事务的概念,需要能够定义非常明确的边界。事务要有非常明确的开始和结束点。SQL Server中的每一条SELECT、INSERT、UPDATE和DELETE语句都是隐式事务的一部分。即使只发出一条语句,也会把这条语句当做一个事务-要么执行语句中的所有内容,要么什么都不执行。但是如果需要的不只是一条,可能是多条语句呢?在这种情况下,就需要有一种方法来标记事务的开始和结束,以及事务的成功或失败。可以使用一些T-SQL语句在事务中"标记"这些点。 BEGIN TRAN:设置起始点。 COMMIT TRAN:使事务成为数据库中永久的、不可逆转的一部分。 ROLLBACK TRAN:本质上说想要忘记它曾经发生过。 SAVE TRAN:创建一个特定标记符,只允许部分回滚。
Cherise_huang 2015-07-09
  • 打赏
  • 举报
回复
可以让多个用户同时调用同一个存储过程时依次执行,而不是同时执行 可以使用事务和锁来操作 有一种叫应用程序锁的锁也许能满足你的需要 您可以通过sp_getapplock 来获得特定的锁,以锁定该过程,当该过程完成后,可以使用sp_releaseapplock;来释放锁 exec sp_getapplock 'ProcLock','Exclusive','session' exec 实际的存储过程 exec sp_releaseapplock 'ProcLock','session' http://www.cnblogs.com/wenjl520/archive/2012/08/24/2654412.html
dsa88885555 2015-07-09
  • 打赏
  • 举报
回复
引用 2 楼 shoppo0505 的回复:
调用时 锁资源 begin tran end tran
不好意思,不懂啥意思
shoppo0505 2015-07-09
  • 打赏
  • 举报
回复
调用时 锁资源 begin tran end tran
dsa88885555 2015-07-09
  • 打赏
  • 举报
回复

34,575

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧