数据库阻塞和死锁在程序开发过程经常出现,怎么样避免呢?下面通过Demo简单模拟下,数据库发生阻塞和死锁的现象:
一、数据库阻塞:
数据库阻塞的现象:第一个连接占有资源没有释放,而第二个连接需要获取这个资源。如果第一个连接没有提交或者回滚,
第二个连接会一直等待下去,直到第一个连接释放该资源为止。对于阻塞,数据库无法处理,所以对数据库操作要及时地提交或
者回滚。
Demo:
--创建表
create table tb(id int,createtime date);
--插入测试数据
insert into tb select 1,sysdate from dual;
insert into tb select 2,sysdate from dual;
insert into tb select 3,sysdate from dual;
commit;
第一个连接,不提交或者回滚:
SQL> update tb set id=2 where id=1;
1 row updated
第二个连接,一直在运行:
SQL> update tb set id=2 where id=1;
因为第一个连接占有tb表没有释放资源,而第二个连接一直在等待第一个连接释放该资源。
二、数据库死锁:
数据库死锁的现象:第一个连接占有资源没有释放,准备获取第二个连接所占用的资源,而第二个连接占有资源没有释放,
准备获取第一个连接所占用的资源。这种互相占有对方需要获取的资源的现象叫做死锁。对于死锁,数据库处理方法:牺牲一个
连接,保证另外一个连接成功执行。
Demo:
--创建测试表t1
create table t1(id int,createtime date);
insert into t1 select 1,sysdate from dual;
insert into t1 select 2,sysdate from dual;
insert into t1 select 3,sysdate from dual;
commit;
--创建测试表t2
create table t2(id int,createtime date);
insert into t2 select 1,sysdate from dual;
insert into t2 select 2,sysdate from dual;
insert into t2 select 3,sysdate from dual;
commit;
第一个连接,在command窗口中运行:
begin
--先修改t1
update t1 set id=2
where id=1;
--等待20s
dbms_lock.sleep(20);
--再修改t2
update t2 set id=2
where id=1;
end;
/
运行结果:
ORA-00060: 等待资源时检测到死锁
ORA-06512: 在 line 9
第二个连接:
begin
--先修改t2
update t2 set id=2
where id=1;
--等待20s
dbms_lock.sleep(20);
--再修改t1
update t1 set id=2
where id=1;
end;
/
运行结果:
PL/SQL procedure successfully completed
因为第一个连接占有表t1,想要获取表t2的资源,而第二个连接占有表t2,想要获取表t1的资源,这种互相占有对方想要获取的资
源,满足死锁现象。最后第一个连接报异常退出,而第二个连接执行成功。