并发插入重复问题

jldzy 2014-07-09 03:20:40
在存储过程里面用下面语句插入 主键是sid,eid,type , 并发量大的时候 重复非常大,老是在提示有重复, 有什么办法控制?

begin try
if @value is not null
begin
if exists(select 1 from xxx where sid=@id and eid=@eid and type=@type)
update xxxx
else
insert into xxx

end
end try
BEGIN CATCH

IF @@TRANCOUNT > 0
BEGIN
ROLLBACK TRAN
END
RAISERROR

end CATCH
...全文
285 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
Tiger_Zhao 2014-07-10
  • 打赏
  • 举报
回复
难以想象的业务!
两个线程会生成相同主键的记录,而且你只通过事务让它们争先,是否可以理解为两者生成的非主键数据也是相同的?
如果相同,就没有冲突,就不需要事务了!
既然你无法在开始就充两个线程中划分操作范围,重复计算不能避免,那么重复保存也是可以接受的。
除了日志会增加,去掉事务后执行速度是有提高的。
walkeeper 2014-07-10
  • 打赏
  • 举报
回复
用TRAN可以控制一下吧,光用TRY CATCH对并发没啥作用的。
xiaoxiangqing 2014-07-10
  • 打赏
  • 举报
回复
只能通过唯一索引去控制
liuhui04403 2014-07-10
  • 打赏
  • 举报
回复
为什么不额外增加一个类似的临时表,然后对临时表做处理之后,全部insert 到final 表里面呢?
Andy-W 2014-07-09
  • 打赏
  • 举报
回复
try :

if @value is null return

begin try
      begin transaction

    update xxxx 
      set 
      where sid=@id and eid=@eid and type=@type
 
    if @@rowcount =0
		insert into xxx ....
     	
      commit transaction
end try
begin catch
      declare @Error nvarchar(2047)
      set @Error = error_message()
      raiserror 50001 @Error
      if @@trancount > 0 
         rollback transaction
end catch
jldzy 2014-07-09
  • 打赏
  • 举报
回复
问题是 现在是来至多个线程的。
shaoming01 2014-07-09
  • 打赏
  • 举报
回复
如果并发的线程来源于同一个进程的话,可以试试在内存里做个KeyLock来防止这种并发.
jldzy 2014-07-09
  • 打赏
  • 举报
回复
当两个同时查询这个的时候你就要重复了, 在你查的时候别人不允许查同一笔记录, 当这记录不存在的时候 怎么办 ?
jldzy 2014-07-09
  • 打赏
  • 举报
回复
还有没看到你的begin tran 啊,,, 没有复制到帖子里面去, 当两个同时查询这个的时候你就要重复了, 在你查的时候别人不允许查同一笔记录 这个怎么控制?
SQL77 2014-07-09
  • 打赏
  • 举报
回复
if exists(select 1 from xxx where sid=@id and eid=@eid and type=@type) 当两个同时查询这个的时候你就要重复了, 在你查的时候别人不允许查同一笔记录, 或者update xxxx --update 是肯定有先有后的。 if @@rowcount=0 insert 还有没看到你的begin tran 啊
發糞塗牆 2014-07-09
  • 打赏
  • 举报
回复
加唯一索引。

34,590

社区成员

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

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