在说明问题之前我们先来看一段经常性使用的代码
function fun(){
开启事务
try{
var count = find();
if(count<1){
insert();
}
提交事务
}catch(e){
事务回滚
}
}
在以上代码中我们在一个事务中,先查询是否存在我们要插入的数据,如果不存在则插入数据,存在则不插入数据。我们很当然的认为这很完美,我在代码中进行了唯一性验证,数据表中肯定不会存在相同的数据记录。在单机应用中或不存在高并发情况确实能够保证我们数据的唯一性。在分布式高并发系统中,该写法是无法保证数据表数据的唯一性。
在单应用系统中为保证数据表中数据主键的唯一性一般我们使用的方法有:
1、数据表增加唯一性约束(单一数据库最简单方式)
增加数据表唯一性约束是最简单的方式,只需要在我们需要的字段中增加唯一约束,当插入相同数据时,数据库会验证数据唯一,当存在相同主键时,数据库会抛出异常信息。
2、使用insert select where not exists 方式
数据表插入语句使用insert select 方式,如在temp_table中增加名称为name1的数据记录,名字列唯一
insert into temp_table(name) select 'name1' from dual where not exists(select 1 from temp_table where name ='name1');
3、使用同步(synchronous)
程序保存代码块中增加并发同步控制,该方法可以防止并发执行,单程序效率会降低。
更新语句写法
for update显示加锁
把udpate语句写在前边,先把数量-1,之后select出库存如果>-1就commit,否则rollback。
update products set quantity = quantity-1 WHERE id=3;
select quantity from products WHERE id=3 for update;
update语句在更新的同时加上一个条件
quantity = select quantity from products WHERE id=3;
update products set quantity = ($quantity-1) WHERE id=3 and queantity = $quantity;