多线程数据重复插入

hling 2010-10-14 05:22:02
一个多线程运行Sql的插入数据


set @str=N'insert into ulook(uname,cname,addtime) SELECT a.uname,'''+@cname +''',GETDATE()
FROM per as a WHERE CHARINDEX('',''+LTRIM(id)+'','', '','+@perid+','')>0
AND NOT EXISTS(SELECT 1 FROM ulook WHERE uname = a.uname AND cname = '''+@cname+''')'
exec sp_executesql @str




可是最后还是有重复的数据插入,怎么回事?
...全文
388 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
hling 2010-10-15
  • 打赏
  • 举报
回复

begin tran
select 1 from ulook with (tablockx) where 1>2
set @str=N'insert into ulook(uname,cname,addtime) SELECT a.uname,'''+@cname +''',GETDATE()
FROM per as a WHERE CHARINDEX('',''+LTRIM(id)+'','', '','+@perid+','')>0
AND NOT EXISTS(SELECT 1 FROM ulook WHERE uname = a.uname AND cname = '''+@cname+''')'
exec sp_executesql @str
commit tran
set @str= 'select * FROM dbo.per where dbo.per.id in ('+@perid+')'
exec sp_executesql @str


在程序中无法显示出记录

billpu 2010-10-15
  • 打赏
  • 举报
回复
恩 应该是的 前面那个select语句通过 返回一个空集合,你输出的应该是这个集合
billpu 2010-10-15
  • 打赏
  • 举报
回复
蛮奇怪的 没理由sqlserver通过,前台程序调用出错的
会不会是返回了第一个记录集(空集)
你是用ado调用的吧,我记得ado有一个方法是用Recordset的NextRecordset 你可以试试
hling 2010-10-15
  • 打赏
  • 举报
回复
不用锁会有重复,用锁,没有重复,但最后返回数据出不来
billpu 2010-10-15
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 hling 的回复:]

不用锁就正常
[/Quote]
...之所以用锁就是要解决你的并发问题,你前台的调用方式如何
chenyu112 2010-10-15
  • 打赏
  • 举报
回复
呵呵,个人习惯
如果有大量的业务,我才用tran,否则单独一条更新没有用
chenyu112 2010-10-15
  • 打赏
  • 举报
回复
改成这样呢

begin tran
select 1 from ulook with (tablockx) where 1>2
set @str=N'insert into ulook(uname,cname,addtime) SELECT a.uname,'''+@cname +''',GETDATE()
FROM per as a WHERE CHARINDEX('',''+LTRIM(id)+'','', '','+@perid+','')>0
AND NOT EXISTS(SELECT 1 FROM ulook WHERE uname = a.uname AND cname = '''+@cname+''')'
exec sp_executesql @str
set @str= 'select * FROM dbo.per where dbo.per.id in ('+@perid+')'
exec sp_executesql @str

commit tran


没有仔细看你的业务,其实一个插入的话,可以不用tran的
hling 2010-10-15
  • 打赏
  • 举报
回复
不用锁就正常
hling 2010-10-15
  • 打赏
  • 举报
回复
插入是可以但这句


set @str= 'select * FROM dbo.per where dbo.per.id in ('+@perid+')'
exec sp_executesql @str



无法返回数据
hling 2010-10-15
  • 打赏
  • 举报
回复
在sql里运行就没事,但在程序就显示不了数据,最后还要返回数据处理
billpu 2010-10-15
  • 打赏
  • 举报
回复
奇怪我这边测试没问题,你那边是无法显示刚刚插入的记录还是所有的记录
billpu 2010-10-14
  • 打赏
  • 举报
回复
where 1>2
billpu 2010-10-14
  • 打赏
  • 举报
回复
试试

begin tran
select 1 from ulook with (tablockx) where 1<2
你的语句
commit tran
hling 2010-10-14
  • 打赏
  • 举报
回复
对uname,cname进行唯一性约束这个行,是可以不重复输入了,但程序出错,还要判断出来
billpu 2010-10-14
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 hling 的回复:]

NOT EXISTS怎么会判断不出来
[/Quote]
因为有两个以上进程同时调用这个存储过程(数据并不存在),所以造成where逻辑通过
billpu 2010-10-14
  • 打赏
  • 举报
回复
看错地方了 原来不是一个表...
那只能写在语句前面加锁了
hling 2010-10-14
  • 打赏
  • 举报
回复
NOT EXISTS怎么会判断不出来
billpu 2010-10-14
  • 打赏
  • 举报
回复
可以建约束或者唯一索引来定义
或者你可以试一下 狠点
select 的时候给来个表锁
set @str=N'insert into ulook(uname,cname,addtime) SELECT a.uname,'''+@cname +''',GETDATE()
FROM per with (xlock, tablock) as a WHERE CHARINDEX('',''+LTRIM(id)+'','', '','+@perid+','')>0
AND NOT EXISTS(SELECT 1 FROM ulook WHERE uname = a.uname AND cname = '''+@cname+''')'
exec sp_executesql @str
SQLCenter 2010-10-14
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 hling 的回复:]

如何在多线程中,防止ulook插入uname,cname相同的数据
[/Quote]

只能在数据库级进行约束了,对uname,cname进行唯一性约束。
hling 2010-10-14
  • 打赏
  • 举报
回复
如何在多线程中,防止ulook插入uname,cname相同的数据
加载更多回复(4)

34,588

社区成员

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

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