日期:2014-05-16  浏览次数:21222 次

SQLSERVER重复插入数据
数据库是SQLSERVER2008版的,在存储过程中先对数据进行逻辑检查,然后使用事务存放数据,所以重复插入数据应该是不可能发生的。使用了一年时间,发现有两笔数据重复插入了。发现的两笔数据是在很短的时间里同时插入的,比如,第一笔数据插入时间是"2013-05-27 12:45:34:123",第二笔数据是" 2013-05-27 12:45:34:236"。不知这是什么情况?
------解决方案--------------------
并发控制不够严格

应该在一个语句中判断,insert into ... select ... where not exists (...)
或者判断时就锁定需要插入的表(对性能影响大,一般不建议)

------解决方案--------------------
所有事务封装后,要么全部成功,要么全部失败,这样不会出现重复记录,可能是你哪个地方手动操作过,或逻辑没有考虑周全,导致重复插入了。
------解决方案--------------------
嗯,很多时候都是先一个exists 判断,然后一系列的操作
这种事控制不住并发的。
------解决方案--------------------
一种是从程序段避免重复提交
还有就是锁表了,这种要尽可能的让事务小,否则容易阻塞。
------解决方案--------------------
WEB程序出现这种情况 通常是用户同时点击了多次 短时间触发多次事件造成的,可以在前台页面做一些控制,比如CSDN论坛你连续提交回复信息是不能提交成功的。。。。
------解决方案--------------------


引用:
Quote: 引用:

一种是从程序段避免重复提交
还有就是锁表了,这种要尽可能的让事务小,否则容易阻塞。

避免重复提交是在存储过程中,首先就做了检查。
锁表的话,应该是不可取的,会有大量的死锁存在

4楼说了sp做这种判断是不能防止并发的
你在判断完之后INSERT 之前这段“空白期”在有一个提交就出现重复了。
你的重复也真是这样造成的
------解决方案--------------------
大家看一下代码的顺序:
执行一个update的时候,因为是开的显示事务,所以该行会被锁死,那么其他的人操作该行时,肯定是等待。
所以重复提交的设想是不存在。

我的观点是,有人在数据库手动提交新增过。
------解决方案--------------------
那你的程序逻辑存在漏洞,事务是封装的,按你的代码思路,不存在提交两次的可能。
------解决方案--------------------
这个就不清楚了,那你用日志查看的工具吧,看看日志中记录的这条重复数据插入的时间,这样结合上下的日志分析。
------解决方案--------------------
多用户同时操作的情况,你的控制是完全有可能插入重复数据的。
因为Insert只锁住一行数据,
这时候其他用户可以随意插入数据。
应该在插入数据前加上一个查询判断,1楼的判断。