- insert 阻塞概念
- 1、无主键插入同样的数据
- 2、 有主键时插入同样的数据
insert 阻塞概念
insert 阻塞情况不多见,最常见的情况是,你有一个带主键的表,或者有唯一性约束,但有两个会话视图用
同样的值插入一行,但是如果这样,其中一个会话会被阻塞,知道另一个会话,提交或者回滚为止;
如果另外一个会话提交,那么阻塞的会话会收到一个错误,指出存在一个重复值;倘若另一会话回滚,在这种情况下
阻塞的会话则会成功。还有一种情况,可能存在多个表通过引用完整性约束相互连接。对子表的插入可能会阻塞,如果它依赖父表中的行正在创建或删除。发生insert 阻塞 通常因为应用允许最终用户自己生成主键/唯一列值。为避免这种情况,最容易的做法是使用一个序列或sys_guid()内置函数来生成主键/唯一列值。序列/sys_guid()是被设计在用于多用户
环境中,以高并发生成唯一键值。如果这两个都没法用,并且必须运行用户生成可能重复的键,那应该使用手工锁
来避免这个问题,这里的手工锁是通过dbms_lock 包来实现
1、无主键插入同样的数据
来看员工emp_a表 此时没有主键 数据如下。
此时有两个用户向员工表中插入 信息7935,‘Jones’,‘SALESMAN’,而第一个用户还未提交,第二个用户就
进行插入。
第一个用户插入数据
INSERT INTO emp_a VALUES (7935, 'Jones', 'SALESMAN');
第二个用户插入数据,此时第一个用户并未提交,此时第二个用户能插入数据吗?
看到结果也能插入 我们两个用户都进行提交。
查看数据,很明显 该数据插入了2条
当然这不是我们想看到的,所以 我们给员工表在编号上加上了主键
继续看如下实例
2、 有主键时插入同样的数据
---删除数据
DELETE FROM emp_a t WHERE t.empno = 7935 ;
--增加主键
alter table emp_a add constraint pk_emp_a primary key (empno);
然后我们再次重复先前的插入操作。
看到用户1在插入数据后,还未及时提交,而用户2进行插入时发生了阻塞,
此时会有两种情况发生
1、用户1觉得插入数据没有问题,进行了提交,提交后用户2就会提示错误 违反主键约束
2、用户1觉得插入数据好像有问题,进行了回滚 ,那用户2就会成功插入数据
所以解决避免重复数据插入的方法之一就是主键最好由系统控制,而不是由用户控制。