并发导入 数据唯一性校验问题

x44348428 2011-06-02 04:40:55
我现在是要支持多个客户端并发导入资料
目前的做法的是 每个用户执行导入 就单起一个线程
比如:A、B用户同时在导入

那A用户开始校验 身份证的唯一性(唯一性校验的字段有很多,如:客户编号、手机号码)
校验成功的话就拼insert的Sql
sql如下:
INSERT INTO xxx("FunctionCode", "FunctionName") VALUES ('aaaaaaaaa', 'bbbbbbbbbb');
INSERT INTO xxx("FunctionCode", "FunctionName") VALUES ('aaaaaaaaa', 'bbbbbbbbbb');
直到1000条 再把这个sql传到数据库,用存储过程执行

现在的问题有两个
1、当用户A在业务层拼sql的时候(还没到1000条)
此时用户B也在校验身份证唯一性 那有可能A用户的记录 跟B用户的记录有重复insert
2、当用户A把1000条sql语句提交到数据库里去执行的时候(还没执行完) 那此时用户B也在校验身份证唯一性 那也有可能A用户的记录 跟B用户的记录有重复insert

谢谢!
...全文
423 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
Shawn 2011-06-02
  • 打赏
  • 举报
回复
--解决方案1
#1.为表建立唯一索引(用唯一性校验的4个字段)
#2.各个线程用主键和唯一性字段校验,如果校验失败,则返回给客户ErrorCode.校验成功的拼insert语句
#3.调用存储过程insert,注意,此时还有可能产生重复的数据.
#4.解决#3的方法为,为每条insert语句加上 TRY CATCH,如果 CATCH 到的异常是主键冲突或唯一索引冲突,则证明其它线程已经insert此数据,返回给客户ErrorCode.

--解决方案2
#1.在进行每条insert语句时,加表锁.并做判断:
IF NOT EXISTS(SELECT 1 FROM tb WHERE keyField = @keyField)
AND NOT EXISTS(SELECT 1 FROM tb WHERE field1 = @field1 AND field2 = @field2 AND field3 = @field3 AND field4 = @field4)
BEGIN
--IINSERT INTO xxx("FunctionCode", "FunctionName") VALUES ('aaaaaaaaa', 'bbbbbbbbbb');
END
ELSE
BEGIN
--返回ErrorCode
END

--解决方案3
用另外一个表,让所有insert语句排队.相当于单线程操作.
http://adyhpq.blog.163.com/blog/static/3866700201011243538718/
君_洛洛 2011-06-02
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 x44348428 的回复:]
还有就是我这边需要唯一性校验的字段 有4个(除了主键以外)
[/Quote]
x44348428 2011-06-02
  • 打赏
  • 举报
回复
还有就是我这边需要唯一性校验的字段 有4个(除了主键以外)
君_洛洛 2011-06-02
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 x44348428 的回复:]
用唯一约束的话 如何把唯一校验失败的结果返回出来给用户呢?
[/Quote]
如果插入失败,你既然可以捕捉到错误,你可以返回给你当前插入失败的客户
x44348428 2011-06-02
  • 打赏
  • 举报
回复
用唯一约束的话 如何把唯一校验失败的结果返回出来给用户呢?
君_洛洛 2011-06-02
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 x44348428 的回复:]
谢谢楼上两位的回答,但我这边情况有点特殊。如果唯一性校验没通过的话,我得需要知道哪一条记录的哪个字段没通过校验,并在导入结束的时候告知用户。
[/Quote]
如果需要验证唯一的,可以弄个唯一约束,没必要弄那么复杂
x44348428 2011-06-02
  • 打赏
  • 举报
回复
谢谢楼上两位的回答,但我这边情况有点特殊。如果唯一性校验没通过的话,我得需要知道哪一条记录的哪个字段没通过校验,并在导入结束的时候告知用户。
-晴天 2011-06-02
  • 打赏
  • 举报
回复
为什么要拼成1000条再插入呢?
直接
insert into tb select @a,@b,@c,@d where not exists(select 1 from tb where a=@a or b=@b or c=@c or d=@d)
就行了.
BigInt 2011-06-02
  • 打赏
  • 举报
回复
有个语句not exists
搂主可以研究下,应该有你需要的答案

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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