日期:2014-05-20  浏览次数:20869 次

数据库并发问题
两个操作员同时添加采购订单,    
此时数据库中采购订单表中记录为    
1,2,3,4,5(这个是主键)    
第一个请求的客户端会去查询这个表,根据查到的结果(5条记录)确定自己的订单号为6    
此时这个操作员正在填写订单的其他信息,没有插入这条数据    
第二个请求的客户端会去查询这个表,根据查到的结果(5条记录)确定自己的订单号为6    
此时这个操作员正在填写订单的其他信息,没有插入这条数据    
这样就有两个主键都是6的记录准备插入这个表,那肯定是其中一个成功,另一个失败    
这个问题可不可以解决。    
我想让它实现成第一个把自己的订单号确定为6,另一个为7。    
好像锁并不能解决问题,因为锁不会锁定一条不存在的记录。

------解决方案--------------------
订单号码永远向前递增,不靠自增字段实现



------解决方案--------------------
自增字段实现

在你保存 时 确定自己的订单号
insert ... (select isnull(max(id),0)+1 from tabel)
------解决方案--------------------
我想一楼的意思也就是,新建一个表,用一次就+1不加入事务,无论本次是否成功,总是加1,
------解决方案--------------------
1. 这样不行的,要么用一个自增字段,然后Insert后你再更新你这个订单号码。
2. 你在数据库中建立一个表,就是给用户有一个取号的功能,取了这个号,别人再点新增时就重取号。意思也就是不管用户是否真的保存,只要点了新增后就会产生一个号码,这样号码就不会冲突了。
3. 你保存时才产生号码再显示给你的用户看是什么号码。
------解决方案--------------------
这样好象也不行吧,自增的怎么可以改呢!
------解决方案--------------------
建议用uniqueidentifier作主键,就不可能重复了
------解决方案--------------------
很多种方案可以解决这个问题:
1.使用自动增加的主键,这种主键是在插入的时候增加。而不是查询的时候增加。听说只有在微秒级并发的时候才可以会产生冲突。我没有遇到过这种情况
2.使用uniqueidentifier这个自然是不会重复的了
3.使用另外一个表来保存最大值。当有纪录插入的时候整个表锁。但是我个人觉得完全没有必要做到这样,因为这样会极大的影响程序的性能。

想想看真正能微秒级的并发会有几次?插入10万次以后失败一次,别人不会说你的程序写的多么多么烂吧。但是,如果每次插入数据要插3分钟可能用户就会是另外的想法了