我也问个技术问题,SQL Server存储过程的并发执行问题

时间:2021-11-10 04:25:24
有没有一种方法对存储过程进行限制,把并发执行转换为顺序执行,为了说明问题,假设有一个存储过程:
create proc pTest 
as
begin
(1)如果Ptest发生并发执行情况,希望在此处,能够等待,直到首先执行此过程的那个进程结束,执行--Start后续代码
  --Start
(2)
  下面代码禁止并发执行
  .....
  .....
end

不知道有没有交代清楚,重新复述一遍,假设有多个过程调用pTest,除了第一个,后续的调用者希望在(1)处能够判断出其他进程正在执行此过程,在(1)处原地等待,直到前一个结束,开始执行后面的代码


89 个解决方案

#1


也就是相当于其他语言中的临界区的概念,因为实际过程中,的确有些不允许并发执行

#2


我的一个存储过程跑了还几年都没问题,但就在今天,不知什么原因中间差了几个毫秒被调用,因为过程执行时间较长,大概几百个毫秒,结果发给病区的药品翻倍,刚刚手工处理,产生退药单,真晕

#3


个人觉得貌似做不到你说的这个功能。坐等mark

#4


1.可以人为控制,自己建一个队列。 建立一个队列表。TABLE MQ (spid int ,stat)
create proc pTest 
as
begin
if exists (select  1 from MQ )
return
else
insert into mq values (@@SPID)
继续下面的动作
最后删除这个记录

end


#5


不知“锁”能不能实现这样的效果,就是存储过程刚开始执行时,先判断某个表是否被锁了,没锁,就锁上,再继续执行;如果锁上了,就等待解锁了,自己锁上,再继续执行。
对“锁”了解不深,只是凭感觉说说。

#6


引用 5 楼 zbdzjx 的回复:
不知“锁”能不能实现这样的效果,就是存储过程刚开始执行时,先判断某个表是否被锁了,没锁,就锁上,再继续执行;如果锁上了,就等待解锁了,自己锁上,再继续执行。
对“锁”了解不深,只是凭感觉说说。

数据库中的锁一般SQL Server自己加的,当然也可以手动加。但是问题是,你要锁定这个表,可能不只是这个存储过程用,其他的存储过程,或者操作可能也用这个表。你把这个表锁住了,可能导致其他人也没法访问这个表。和楼主本身的需求不符合

#7


还是得用锁吧。。。

#9


引用 8 楼 yenange 的回复:
http://blog.csdn.net/yenange/article/details/78903480

@yenange  这个办法很不错。楼主可以参考下。

#10


引用 楼主 yisuylm 的回复:
有没有一种方法对存储过程进行限制,把并发执行转换为顺序执行,为了说明问题,假设有一个存储过程:
create proc pTest 
as
begin
(1)如果Ptest发生并发执行情况,希望在此处,能够等待,直到首先执行此过程的那个进程结束,执行--Start后续代码
  --Start
(2)
  下面代码禁止并发执行
  .....
  .....
end

不知道有没有交代清楚,重新复述一遍,假设有多个过程调用pTest,除了第一个,后续的调用者希望在(1)处能够判断出其他进程正在执行此过程,在(1)处原地等待,直到前一个结束,开始执行后面的代码

这种想法会有点用没,但是会拖累整个系统。
因为如果需要用到这种机制,单个存储过程执行时间肯定很长了,还做队列,这要让用户等多久?

其实表已经有锁止功能,不知道你这么做会型能会有多少改进?
期待测试结果。

#11


引用 10 楼 shoppo0505 的回复:
Quote: 引用 楼主 yisuylm 的回复:

有没有一种方法对存储过程进行限制,把并发执行转换为顺序执行,为了说明问题,假设有一个存储过程:
create proc pTest 
as
begin
(1)如果Ptest发生并发执行情况,希望在此处,能够等待,直到首先执行此过程的那个进程结束,执行--Start后续代码
  --Start
(2)
  下面代码禁止并发执行
  .....
  .....
end

不知道有没有交代清楚,重新复述一遍,假设有多个过程调用pTest,除了第一个,后续的调用者希望在(1)处能够判断出其他进程正在执行此过程,在(1)处原地等待,直到前一个结束,开始执行后面的代码

这种想法会有点用没,但是会拖累整个系统。
因为如果需要用到这种机制,单个存储过程执行时间肯定很长了,还做队列,这要让用户等多久?

其实表已经有锁止功能,不知道你这么做会型能会有多少改进?
期待测试结果。

不是这样的,我在挺多客户遇到过这个问题。大量的并发拥进来会导致数据库严重阻塞,等待,,这个存储过程的执行时间会变得特别慢,用队列的办法来做,反而速度更快。不过我写这个办法,也只是自己想的,没有实际运用过。

#12


引用 楼主 yisuylm 的回复:
有没有一种方法对存储过程进行限制,把并发执行转换为顺序执行,为了说明问题,假设有一个存储过程:
create proc pTest 
as
begin
(1)如果Ptest发生并发执行情况,希望在此处,能够等待,直到首先执行此过程的那个进程结束,执行--Start后续代码
  --Start
(2)
  下面代码禁止并发执行
  .....
  .....
end

不知道有没有交代清楚,重新复述一遍,假设有多个过程调用pTest,除了第一个,后续的调用者希望在(1)处能够判断出其他进程正在执行此过程,在(1)处原地等待,直到前一个结束,开始执行后面的代码

这种想法会有点用没,但是会拖累整个系统。
因为如果需要用到这种机制,单个存储过程执行时间肯定很长了,还做队列,这要让用户等多久?

其实表已经有锁止功能,不知道你这么做会型能会有多少改进?
期待测试结果。

引用 11 楼 z10843087 的回复:
Quote: 引用 10 楼 shoppo0505 的回复:

Quote: 引用 楼主 yisuylm 的回复:

有没有一种方法对存储过程进行限制,把并发执行转换为顺序执行,为了说明问题,假设有一个存储过程:
create proc pTest 
as
begin
(1)如果Ptest发生并发执行情况,希望在此处,能够等待,直到首先执行此过程的那个进程结束,执行--Start后续代码
  --Start
(2)
  下面代码禁止并发执行
  .....
  .....
end

不知道有没有交代清楚,重新复述一遍,假设有多个过程调用pTest,除了第一个,后续的调用者希望在(1)处能够判断出其他进程正在执行此过程,在(1)处原地等待,直到前一个结束,开始执行后面的代码

这种想法会有点用没,但是会拖累整个系统。
因为如果需要用到这种机制,单个存储过程执行时间肯定很长了,还做队列,这要让用户等多久?

其实表已经有锁止功能,不知道你这么做会型能会有多少改进?
期待测试结果。

不是这样的,我在挺多客户遇到过这个问题。大量的并发拥进来会导致数据库严重阻塞,等待,,这个存储过程的执行时间会变得特别慢,用队列的办法来做,反而速度更快。不过我写这个办法,也只是自己想的,没有实际运用过。

建议前台程序使用lock锁

#13


该回复于2017-12-28 19:27:21被版主删除

#14


该回复于2017-12-28 19:28:59被版主删除

#15


while 1=1
Begin
      if Locked=0
             break
End

#16


引用 8楼_大约在冬季_ 的回复:
http://blog.csdn.net/yenange/article/details/78903480
我也问个技术问题,SQL Server存储过程的并发执行问题我也问个技术问题,SQL Server存储过程的并发执行问题

#17


两个思路:

1. 在(1)处,建立一个全局临时表,往里面插入一个标记符。所有执行到这里的程序去判断标记符对应的数值,有没有比当前值小的记录,有,就停止执行。
 这样做的弊端必定是给程序的并发带来很大的延迟;

2. 整个存储过程分成 2 个事务,在(1)处设置一个 serializable 的级别,其他事务当然就停下来等待了。


#18


我也问个技术问题,SQL Server存储过程的并发执行问题
learning~

#19


感谢各位回复,有些想法现在还来不及验证,今天的事故导致了严重的后果,很多病人今天的费用也翻了一翻,一会写个存储过程,先把费用红冲,确保计费正确

#20


墨菲定律得到验证,我们十几个客户跑了几年,第1次发生这种事件

#21


这个帖子好。

#22


关注,学习 我也问个技术问题,SQL Server存储过程的并发执行问题

#23



存储过程的并发执行、串行执行是什么?  我不懂!


我也问个技术问题,SQL Server存储过程的并发执行问题


#24


昨天晚上工作到三点钟,把多收的费用对冲处理完成,一共有3万多元,后来花一个小时确定解决方案,确保以后不再发生此类故障,具体的措施就是:
允许存储过程反复执行,对同样的数据,根据业务特点,无论执行多少次,都会生成相同的复合序列,对这部分复合序列做唯一性索引进行约束,这样,不用加锁,除了第一个能够成功,其他的后续过程在插入数据时由于约束的原因会失败,从而确保数据无异常记录

#25


引用 24 楼 yisuylm 的回复:
昨天晚上工作到三点钟,把多收的费用对冲处理完成,一共有3万多元,后来花一个小时确定解决方案,确保以后不再发生此类故障,具体的措施就是:
允许存储过程反复执行,对同样的数据,根据业务特点,无论执行多少次,都会生成相同的复合序列,对这部分复合序列做唯一性索引进行约束,这样,不用加锁,除了第一个能够成功,其他的后续过程在插入数据时由于约束的原因会失败,从而确保数据无异常记录

辛苦辛苦。 我也问个技术问题,SQL Server存储过程的并发执行问题 .通过唯一约束来实现也是一个不错的办法.

#26


如果你的存储过程中的操作不受事务影响,随便弄个表自己加锁也是一样的


随便建一张表,insert 一条记录
create table tb_lock(lock bit default 0);
insert tb_lock values(0);
go

-- 存储过程中,对过乐来防止并行
create proc p_test
as
begin tran;
-- 如果这个存储过程已经在捃,则这里无法得到锁,只有等锁释放后才能继续
select * from tb_lock with(updlock)
--- 你的处理
rollback; -- 释放锁
go

#27


引用 24 楼 yisuylm 的回复:
昨天晚上工作到三点钟,把多收的费用对冲处理完成,一共有3万多元,后来花一个小时确定解决方案,确保以后不再发生此类故障,具体的措施就是:
允许存储过程反复执行,对同样的数据,根据业务特点,无论执行多少次,都会生成相同的复合序列,对这部分复合序列做唯一性索引进行约束,这样,不用加锁,除了第一个能够成功,其他的后续过程在插入数据时由于约束的原因会失败,从而确保数据无异常记录

既然有唯一这个特性,那也不是非得串行了

#28


最好自己去控制

#29


引用 27 楼 zjcxc 的回复:
Quote: 引用 24 楼 yisuylm 的回复:

昨天晚上工作到三点钟,把多收的费用对冲处理完成,一共有3万多元,后来花一个小时确定解决方案,确保以后不再发生此类故障,具体的措施就是:
允许存储过程反复执行,对同样的数据,根据业务特点,无论执行多少次,都会生成相同的复合序列,对这部分复合序列做唯一性索引进行约束,这样,不用加锁,除了第一个能够成功,其他的后续过程在插入数据时由于约束的原因会失败,从而确保数据无异常记录

既然有唯一这个特性,那也不是非得串行了

原来没有唯一性,根据业务特性,加入规则人为产生唯一性

#30


关注,学习 我也问个技术问题,SQL Server存储过程的并发执行问题

#31


关注一下,学习、

#32


若借助前端代码是否会好实现些

#33


引用 32 楼 mcxhh2005 的回复:
若借助前端代码是否会好实现些

please write in English!  我也问个技术问题,SQL Server存储过程的并发执行问题

#34


引用 32 楼 mcxhh2005 的回复:
若借助前端代码是否会好实现些

为什么不发英语

#35


值得观摩学习 我也问个技术问题,SQL Server存储过程的并发执行问题

#36


这里的人个个都是人才,我超喜欢这里 我也问个技术问题,SQL Server存储过程的并发执行问题

#37


引用 6 楼 z10843087 的回复:
Quote: 引用 5 楼 zbdzjx 的回复:

不知“锁”能不能实现这样的效果,就是存储过程刚开始执行时,先判断某个表是否被锁了,没锁,就锁上,再继续执行;如果锁上了,就等待解锁了,自己锁上,再继续执行。
对“锁”了解不深,只是凭感觉说说。

数据库中的锁一般SQL Server自己加的,当然也可以手动加。但是问题是,你要锁定这个表,可能不只是这个存储过程用,其他的存储过程,或者操作可能也用这个表。你把这个表锁住了,可能导致其他人也没法访问这个表。和楼主本身的需求不符合
a

#38


引用 37 楼 maizi991 的回复:
Quote: 引用 6 楼 z10843087 的回复:

[quote=引用 5 楼
不知“锁”能不能实现这样的效果,就是存储过程刚开始执行时,先判断某个表是否被锁了,没锁,就锁上,再继续执行;如果锁上了,就等待解锁了,自己锁上,再继续执行。
对“锁”了解不深,只是凭感觉说说。

数据库中的锁一般SQL Server自己加的,当然也可以手动加。但是问题是,你要锁定这个表,可能不只是这个存储过程用,其他的存储过程,或者操作可能也用这个表。你把这个表锁住了,可能导致其他人也没法访问这个表。和楼主本身的需求不符合
aa

#39


引用 38 楼 maizi991 的回复:
Quote: 引用 37 楼 maizi991 的回复:

Quote: 引用 6 楼 z10843087 的回复:

[quote=引用 5 楼
不知“锁”能不能实现这样的效果,就是存储过程刚开始执行时,先判断某个表是否被锁了,没锁,就锁上,再继续执行;如果锁上了,就等待解锁了,自己锁上,再继续执行。
对“锁”了解不深,只是凭感觉说说。

数据库中的锁一般SQL Server自己加的,当然也可以手动加。但是问题是,你要锁定这个表,可能不只是这个存储过程用,其他的存储过程,或者操作可能也用这个表。你把这个表锁住了,可能导致其他人也没法访问这个表。和楼主本身的需求不符合
a
a
发这个AA,是发错了吗

#40


引用 12 楼 shoppo0505 的回复:
Quote: 引用 楼主 yisuylm 的回复:

有没有一种方法对存储过程进行限制,把并发执行转换为顺序执行,为了说明问题,假设有一个存储过程:
create proc pTest 
as
begin
(1)如果Ptest发生并发执行情况,希望在此处,能够等待,直到首先执行此过程的那个进程结束,执行--Start后续代码
  --Start
(2)
  下面代码禁止并发执行
  .....
  .....
end

不知道有没有交代清楚,重新复述一遍,假设有多个过程调用pTest,除了第一个,后续的调用者希望在(1)处能够判断出其他进程正在执行此过程,在(1)处原地等待,直到前一个结束,开始执行后面的代码

这种想法会有点用没,但是会拖累整个系统。
因为如果需要用到这种机制,单个存储过程执行时间肯定很长了,还做队列,这要让用户等多久?

其实表已经有锁止功能,不知道你这么做会型能会有多少改进?
期待测试结果。

引用 11 楼 z10843087 的回复:
Quote: 引用 10 楼 shoppo0505 的回复:

Quote: 引用 楼主 yisuylm 的回复:

有没有一种方法对存储过程进行限制,把并发执行转换为顺序执行,为了说明问题,假设有一个存储过程:
create proc pTest 
as
begin
(1)如果Ptest发生并发执行情况,希望在此处,能够等待,直到首先执行此过程的那个进程结束,执行--Start后续代码
  --Start
(2)
  下面代码禁止并发执行
  .....
  .....
end

不知道有没有交代清楚,重新复述一遍,假设有多个过程调用pTest,除了第一个,后续的调用者希望在(1)处能够判断出其他进程正在执行此过程,在(1)处原地等待,直到前一个结束,开始执行后面的代码

这种想法会有点用没,但是会拖累整个系统。
因为如果需要用到这种机制,单个存储过程执行时间肯定很长了,还做队列,这要让用户等多久?

其实表已经有锁止功能,不知道你这么做会型能会有多少改进?
期待测试结果。

不是这样的,我在挺多客户遇到过这个问题。大量的并发拥进来会导致数据库严重阻塞,等待,,这个存储过程的执行时间会变得特别慢,用队列的办法来做,反而速度更快。不过我写这个办法,也只是自己想的,没有实际运用过。

建议前台程序使用lock锁

厉害

#41


该回复于2017-12-28 19:26:06被版主删除

#42


learning~

#43


觉得得用锁吧

#44


该回复于2017-12-28 19:28:44被版主删除

#45


BEGIN TRAN用事务呢

#46


该回复于2017-12-28 19:28:28被版主删除

#47


该回复于2017-12-28 19:28:17被版主删除

#48


这个帖子好。

#49


关注,学习 我也问个技术问题,SQL Server存储过程的并发执行问题

#50


learning~

#1


也就是相当于其他语言中的临界区的概念,因为实际过程中,的确有些不允许并发执行

#2


我的一个存储过程跑了还几年都没问题,但就在今天,不知什么原因中间差了几个毫秒被调用,因为过程执行时间较长,大概几百个毫秒,结果发给病区的药品翻倍,刚刚手工处理,产生退药单,真晕

#3


个人觉得貌似做不到你说的这个功能。坐等mark

#4


1.可以人为控制,自己建一个队列。 建立一个队列表。TABLE MQ (spid int ,stat)
create proc pTest 
as
begin
if exists (select  1 from MQ )
return
else
insert into mq values (@@SPID)
继续下面的动作
最后删除这个记录

end


#5


不知“锁”能不能实现这样的效果,就是存储过程刚开始执行时,先判断某个表是否被锁了,没锁,就锁上,再继续执行;如果锁上了,就等待解锁了,自己锁上,再继续执行。
对“锁”了解不深,只是凭感觉说说。

#6


引用 5 楼 zbdzjx 的回复:
不知“锁”能不能实现这样的效果,就是存储过程刚开始执行时,先判断某个表是否被锁了,没锁,就锁上,再继续执行;如果锁上了,就等待解锁了,自己锁上,再继续执行。
对“锁”了解不深,只是凭感觉说说。

数据库中的锁一般SQL Server自己加的,当然也可以手动加。但是问题是,你要锁定这个表,可能不只是这个存储过程用,其他的存储过程,或者操作可能也用这个表。你把这个表锁住了,可能导致其他人也没法访问这个表。和楼主本身的需求不符合

#7


还是得用锁吧。。。

#8


#9


引用 8 楼 yenange 的回复:
http://blog.csdn.net/yenange/article/details/78903480

@yenange  这个办法很不错。楼主可以参考下。

#10


引用 楼主 yisuylm 的回复:
有没有一种方法对存储过程进行限制,把并发执行转换为顺序执行,为了说明问题,假设有一个存储过程:
create proc pTest 
as
begin
(1)如果Ptest发生并发执行情况,希望在此处,能够等待,直到首先执行此过程的那个进程结束,执行--Start后续代码
  --Start
(2)
  下面代码禁止并发执行
  .....
  .....
end

不知道有没有交代清楚,重新复述一遍,假设有多个过程调用pTest,除了第一个,后续的调用者希望在(1)处能够判断出其他进程正在执行此过程,在(1)处原地等待,直到前一个结束,开始执行后面的代码

这种想法会有点用没,但是会拖累整个系统。
因为如果需要用到这种机制,单个存储过程执行时间肯定很长了,还做队列,这要让用户等多久?

其实表已经有锁止功能,不知道你这么做会型能会有多少改进?
期待测试结果。

#11


引用 10 楼 shoppo0505 的回复:
Quote: 引用 楼主 yisuylm 的回复:

有没有一种方法对存储过程进行限制,把并发执行转换为顺序执行,为了说明问题,假设有一个存储过程:
create proc pTest 
as
begin
(1)如果Ptest发生并发执行情况,希望在此处,能够等待,直到首先执行此过程的那个进程结束,执行--Start后续代码
  --Start
(2)
  下面代码禁止并发执行
  .....
  .....
end

不知道有没有交代清楚,重新复述一遍,假设有多个过程调用pTest,除了第一个,后续的调用者希望在(1)处能够判断出其他进程正在执行此过程,在(1)处原地等待,直到前一个结束,开始执行后面的代码

这种想法会有点用没,但是会拖累整个系统。
因为如果需要用到这种机制,单个存储过程执行时间肯定很长了,还做队列,这要让用户等多久?

其实表已经有锁止功能,不知道你这么做会型能会有多少改进?
期待测试结果。

不是这样的,我在挺多客户遇到过这个问题。大量的并发拥进来会导致数据库严重阻塞,等待,,这个存储过程的执行时间会变得特别慢,用队列的办法来做,反而速度更快。不过我写这个办法,也只是自己想的,没有实际运用过。

#12


引用 楼主 yisuylm 的回复:
有没有一种方法对存储过程进行限制,把并发执行转换为顺序执行,为了说明问题,假设有一个存储过程:
create proc pTest 
as
begin
(1)如果Ptest发生并发执行情况,希望在此处,能够等待,直到首先执行此过程的那个进程结束,执行--Start后续代码
  --Start
(2)
  下面代码禁止并发执行
  .....
  .....
end

不知道有没有交代清楚,重新复述一遍,假设有多个过程调用pTest,除了第一个,后续的调用者希望在(1)处能够判断出其他进程正在执行此过程,在(1)处原地等待,直到前一个结束,开始执行后面的代码

这种想法会有点用没,但是会拖累整个系统。
因为如果需要用到这种机制,单个存储过程执行时间肯定很长了,还做队列,这要让用户等多久?

其实表已经有锁止功能,不知道你这么做会型能会有多少改进?
期待测试结果。

引用 11 楼 z10843087 的回复:
Quote: 引用 10 楼 shoppo0505 的回复:

Quote: 引用 楼主 yisuylm 的回复:

有没有一种方法对存储过程进行限制,把并发执行转换为顺序执行,为了说明问题,假设有一个存储过程:
create proc pTest 
as
begin
(1)如果Ptest发生并发执行情况,希望在此处,能够等待,直到首先执行此过程的那个进程结束,执行--Start后续代码
  --Start
(2)
  下面代码禁止并发执行
  .....
  .....
end

不知道有没有交代清楚,重新复述一遍,假设有多个过程调用pTest,除了第一个,后续的调用者希望在(1)处能够判断出其他进程正在执行此过程,在(1)处原地等待,直到前一个结束,开始执行后面的代码

这种想法会有点用没,但是会拖累整个系统。
因为如果需要用到这种机制,单个存储过程执行时间肯定很长了,还做队列,这要让用户等多久?

其实表已经有锁止功能,不知道你这么做会型能会有多少改进?
期待测试结果。

不是这样的,我在挺多客户遇到过这个问题。大量的并发拥进来会导致数据库严重阻塞,等待,,这个存储过程的执行时间会变得特别慢,用队列的办法来做,反而速度更快。不过我写这个办法,也只是自己想的,没有实际运用过。

建议前台程序使用lock锁

#13


该回复于2017-12-28 19:27:21被版主删除

#14


该回复于2017-12-28 19:28:59被版主删除

#15


while 1=1
Begin
      if Locked=0
             break
End

#16


引用 8楼_大约在冬季_ 的回复:
http://blog.csdn.net/yenange/article/details/78903480
我也问个技术问题,SQL Server存储过程的并发执行问题我也问个技术问题,SQL Server存储过程的并发执行问题

#17


两个思路:

1. 在(1)处,建立一个全局临时表,往里面插入一个标记符。所有执行到这里的程序去判断标记符对应的数值,有没有比当前值小的记录,有,就停止执行。
 这样做的弊端必定是给程序的并发带来很大的延迟;

2. 整个存储过程分成 2 个事务,在(1)处设置一个 serializable 的级别,其他事务当然就停下来等待了。


#18


我也问个技术问题,SQL Server存储过程的并发执行问题
learning~

#19


感谢各位回复,有些想法现在还来不及验证,今天的事故导致了严重的后果,很多病人今天的费用也翻了一翻,一会写个存储过程,先把费用红冲,确保计费正确

#20


墨菲定律得到验证,我们十几个客户跑了几年,第1次发生这种事件

#21


这个帖子好。

#22


关注,学习 我也问个技术问题,SQL Server存储过程的并发执行问题

#23



存储过程的并发执行、串行执行是什么?  我不懂!


我也问个技术问题,SQL Server存储过程的并发执行问题


#24


昨天晚上工作到三点钟,把多收的费用对冲处理完成,一共有3万多元,后来花一个小时确定解决方案,确保以后不再发生此类故障,具体的措施就是:
允许存储过程反复执行,对同样的数据,根据业务特点,无论执行多少次,都会生成相同的复合序列,对这部分复合序列做唯一性索引进行约束,这样,不用加锁,除了第一个能够成功,其他的后续过程在插入数据时由于约束的原因会失败,从而确保数据无异常记录

#25


引用 24 楼 yisuylm 的回复:
昨天晚上工作到三点钟,把多收的费用对冲处理完成,一共有3万多元,后来花一个小时确定解决方案,确保以后不再发生此类故障,具体的措施就是:
允许存储过程反复执行,对同样的数据,根据业务特点,无论执行多少次,都会生成相同的复合序列,对这部分复合序列做唯一性索引进行约束,这样,不用加锁,除了第一个能够成功,其他的后续过程在插入数据时由于约束的原因会失败,从而确保数据无异常记录

辛苦辛苦。 我也问个技术问题,SQL Server存储过程的并发执行问题 .通过唯一约束来实现也是一个不错的办法.

#26


如果你的存储过程中的操作不受事务影响,随便弄个表自己加锁也是一样的


随便建一张表,insert 一条记录
create table tb_lock(lock bit default 0);
insert tb_lock values(0);
go

-- 存储过程中,对过乐来防止并行
create proc p_test
as
begin tran;
-- 如果这个存储过程已经在捃,则这里无法得到锁,只有等锁释放后才能继续
select * from tb_lock with(updlock)
--- 你的处理
rollback; -- 释放锁
go

#27


引用 24 楼 yisuylm 的回复:
昨天晚上工作到三点钟,把多收的费用对冲处理完成,一共有3万多元,后来花一个小时确定解决方案,确保以后不再发生此类故障,具体的措施就是:
允许存储过程反复执行,对同样的数据,根据业务特点,无论执行多少次,都会生成相同的复合序列,对这部分复合序列做唯一性索引进行约束,这样,不用加锁,除了第一个能够成功,其他的后续过程在插入数据时由于约束的原因会失败,从而确保数据无异常记录

既然有唯一这个特性,那也不是非得串行了

#28


最好自己去控制

#29


引用 27 楼 zjcxc 的回复:
Quote: 引用 24 楼 yisuylm 的回复:

昨天晚上工作到三点钟,把多收的费用对冲处理完成,一共有3万多元,后来花一个小时确定解决方案,确保以后不再发生此类故障,具体的措施就是:
允许存储过程反复执行,对同样的数据,根据业务特点,无论执行多少次,都会生成相同的复合序列,对这部分复合序列做唯一性索引进行约束,这样,不用加锁,除了第一个能够成功,其他的后续过程在插入数据时由于约束的原因会失败,从而确保数据无异常记录

既然有唯一这个特性,那也不是非得串行了

原来没有唯一性,根据业务特性,加入规则人为产生唯一性

#30


关注,学习 我也问个技术问题,SQL Server存储过程的并发执行问题

#31


关注一下,学习、

#32


若借助前端代码是否会好实现些

#33


引用 32 楼 mcxhh2005 的回复:
若借助前端代码是否会好实现些

please write in English!  我也问个技术问题,SQL Server存储过程的并发执行问题

#34


引用 32 楼 mcxhh2005 的回复:
若借助前端代码是否会好实现些

为什么不发英语

#35


值得观摩学习 我也问个技术问题,SQL Server存储过程的并发执行问题

#36


这里的人个个都是人才,我超喜欢这里 我也问个技术问题,SQL Server存储过程的并发执行问题

#37


引用 6 楼 z10843087 的回复:
Quote: 引用 5 楼 zbdzjx 的回复:

不知“锁”能不能实现这样的效果,就是存储过程刚开始执行时,先判断某个表是否被锁了,没锁,就锁上,再继续执行;如果锁上了,就等待解锁了,自己锁上,再继续执行。
对“锁”了解不深,只是凭感觉说说。

数据库中的锁一般SQL Server自己加的,当然也可以手动加。但是问题是,你要锁定这个表,可能不只是这个存储过程用,其他的存储过程,或者操作可能也用这个表。你把这个表锁住了,可能导致其他人也没法访问这个表。和楼主本身的需求不符合
a

#38


引用 37 楼 maizi991 的回复:
Quote: 引用 6 楼 z10843087 的回复:

[quote=引用 5 楼
不知“锁”能不能实现这样的效果,就是存储过程刚开始执行时,先判断某个表是否被锁了,没锁,就锁上,再继续执行;如果锁上了,就等待解锁了,自己锁上,再继续执行。
对“锁”了解不深,只是凭感觉说说。

数据库中的锁一般SQL Server自己加的,当然也可以手动加。但是问题是,你要锁定这个表,可能不只是这个存储过程用,其他的存储过程,或者操作可能也用这个表。你把这个表锁住了,可能导致其他人也没法访问这个表。和楼主本身的需求不符合
aa

#39


引用 38 楼 maizi991 的回复:
Quote: 引用 37 楼 maizi991 的回复:

Quote: 引用 6 楼 z10843087 的回复:

[quote=引用 5 楼
不知“锁”能不能实现这样的效果,就是存储过程刚开始执行时,先判断某个表是否被锁了,没锁,就锁上,再继续执行;如果锁上了,就等待解锁了,自己锁上,再继续执行。
对“锁”了解不深,只是凭感觉说说。

数据库中的锁一般SQL Server自己加的,当然也可以手动加。但是问题是,你要锁定这个表,可能不只是这个存储过程用,其他的存储过程,或者操作可能也用这个表。你把这个表锁住了,可能导致其他人也没法访问这个表。和楼主本身的需求不符合
a
a
发这个AA,是发错了吗

#40


引用 12 楼 shoppo0505 的回复:
Quote: 引用 楼主 yisuylm 的回复:

有没有一种方法对存储过程进行限制,把并发执行转换为顺序执行,为了说明问题,假设有一个存储过程:
create proc pTest 
as
begin
(1)如果Ptest发生并发执行情况,希望在此处,能够等待,直到首先执行此过程的那个进程结束,执行--Start后续代码
  --Start
(2)
  下面代码禁止并发执行
  .....
  .....
end

不知道有没有交代清楚,重新复述一遍,假设有多个过程调用pTest,除了第一个,后续的调用者希望在(1)处能够判断出其他进程正在执行此过程,在(1)处原地等待,直到前一个结束,开始执行后面的代码

这种想法会有点用没,但是会拖累整个系统。
因为如果需要用到这种机制,单个存储过程执行时间肯定很长了,还做队列,这要让用户等多久?

其实表已经有锁止功能,不知道你这么做会型能会有多少改进?
期待测试结果。

引用 11 楼 z10843087 的回复:
Quote: 引用 10 楼 shoppo0505 的回复:

Quote: 引用 楼主 yisuylm 的回复:

有没有一种方法对存储过程进行限制,把并发执行转换为顺序执行,为了说明问题,假设有一个存储过程:
create proc pTest 
as
begin
(1)如果Ptest发生并发执行情况,希望在此处,能够等待,直到首先执行此过程的那个进程结束,执行--Start后续代码
  --Start
(2)
  下面代码禁止并发执行
  .....
  .....
end

不知道有没有交代清楚,重新复述一遍,假设有多个过程调用pTest,除了第一个,后续的调用者希望在(1)处能够判断出其他进程正在执行此过程,在(1)处原地等待,直到前一个结束,开始执行后面的代码

这种想法会有点用没,但是会拖累整个系统。
因为如果需要用到这种机制,单个存储过程执行时间肯定很长了,还做队列,这要让用户等多久?

其实表已经有锁止功能,不知道你这么做会型能会有多少改进?
期待测试结果。

不是这样的,我在挺多客户遇到过这个问题。大量的并发拥进来会导致数据库严重阻塞,等待,,这个存储过程的执行时间会变得特别慢,用队列的办法来做,反而速度更快。不过我写这个办法,也只是自己想的,没有实际运用过。

建议前台程序使用lock锁

厉害

#41


该回复于2017-12-28 19:26:06被版主删除

#42


learning~

#43


觉得得用锁吧

#44


该回复于2017-12-28 19:28:44被版主删除

#45


BEGIN TRAN用事务呢

#46


该回复于2017-12-28 19:28:28被版主删除

#47


该回复于2017-12-28 19:28:17被版主删除

#48


这个帖子好。

#49


关注,学习 我也问个技术问题,SQL Server存储过程的并发执行问题

#50


learning~