数据库并发问题,CSDN无大神?
求助个问题,流程如下
事务开始:
查询一最大值(数字)
插入一条数据,同一字段值设置为(第一步最大值 + 1)
提交事务
_____________________________
这会有个线程同步问题,比如线程1,2同时查到最大值为10,则可能同时 INSERT 11
而我不能把字段配置成“unique", 因为业务的原因
求助诸位,先谢谢
C语言我知道可以弄LOCK锁函数,但是我想以数据库的方式,不知道有没有解决办法。比如,有没有办法让事务一开始,自动锁定,其他线程进入事务只能等待
如果描述不清,我还是举例算了,表有 产品和 版本两字段
产品,版本
——————————————————————
产品A,1
产品A,2
产品XX,1
产品YY,1
产品YY,2
产品YY,3
如果两个事务同时查到产品A的最大版本2,则同时INSERT (产品A,3)明显就有问题。
(如果你想回答“弄成一个语句,类似insert into xxx values (select max ....)" 就算了,我不需要这样的答案)
insert
数据库
SQL
同步
并发
------解决方案--------------------查完即update +1
即先update 再insert
用提交读。
如果可以降低并发性能可以应用更高的隔离级别,如可重复读。
个见。
------解决方案--------------------我假定:
ta
id tb_name max_n
1 tb 23
2 tc 55
tb
id ....
你从ta表中读取tb对应的max_n 然后插入记录到tb ,max_n +1 作为新记录的 id
那么
begin tran
declare @id int
update ta set max_n=max_n + 1 where tb_name = 'tb'
select @id = max_n from ta
if @error....
commit tran
insert tb ...
如果插入不成功, 在这个进程下max_n +1 的结果(对tb表来说)将被丢弃, 从而行成断号。
如果你的表是这样的设计的话 ta表的记录是非常少的,那么update的操作速度将非常快, 在解决你所说的问题的同时并有效的提高并发量。
------解决方案--------------------上面代码只是示意, 并没有严谨的写, 只表达意思。
------解决方案--------------------我的习惯是,先select出最大值,再加1,再insert。为了防止重复,用主键或是唯一索引。这样,如果重复了,数据库会返回错误。
------解决方案--------------------用事务的话,在当前事务没有提交的情况下,表不能做其他更新操作的吧.事务就是防止并发产生脏数据。所以产生你说的那个情况,不过相应的效率就降低了
------解决方案--------------------
呵呵, 最后一句肯定是看到了的。
本质的区别很大的。
不想重复,又不想等待(哪怕是理论上微秒纳秒级的), 你的要求无解。
------解决方案--------------------1, 既然你自己都说了,另一个进程失败了, 那何谈并发。
2,不要用max
------解决方案--------------------我觉得insert into xx(..., Num) values (..., select max(..))这个方案就不错
不过多并发环境的话可能效率就低了点
------解决方案--------------------流程如下修改就可以了
事务开始:
查询一最大值(数字),同时加排它锁
插入一条数据,同一字段值设置为(第一步最大值 + 1)
提交事务
------解决方案--------------------