创建表来模拟阻塞的问题
使用序列快速创建表:
create sequence s1
start with 1
increment by 1
maxvalue 200
create table t3(id int,name char(30))
insert into t3(id) values(s1.nextval,'aa')
insert into t3(id) values(s1.nextval,'bb')
insert into t3(id) values(s1.nextval,'cc')
创建完成后commit提交
这时查询锁情况可以看到一切正常没有阻塞发生
select * from v$lock where blocked =1
修改t3表中的记录行,使用update语句
update t3 set id = 100 where name = 'aa'
可以看到修改成功,但现在还没有commit,新开一个会话还是旧数据
这时新开一个窗口执行delete语句,此时,由于 delete 操作需要加上与之前 update 操作相同类型的锁,所以阻塞发生,当前事务被挂起。
查看t3表的锁状态:
先找到t3表的id号
select * from all_objects where object_name='T3'
通过v$lock查看阻塞情况
TRX_ID:所属事务ID。
LTYPE:锁类型,TID锁、对象锁。
LMODE:锁模式,S锁:共享锁、X锁:排他锁、IS锁:意向共享锁、IX锁意向排他锁。
BLOCKED:是否阻塞,1为阻塞,0为未阻塞。
TABLE_ID:封锁记录对应的表id,-1表示事务启动自动封锁自身TID
ROW_IDX:TID锁封锁记录行信息
TID:TID锁对象事务ID
IGN_FLAG:0为锁正在使用、1为事务以及条,但是锁资源没有释放,重新封锁可以直接使用
结果中可以看到,事务 6236 被阻塞了,阻塞他的事务为 6227,同样我们也可以通过 V$TRXWAIT 视图排查阻塞,
可以得到相同的结果6234事务在等待6227事务,等待时间为591863。
开启第三个会话通过v$sessions查看具体sql语句:
select sess_id,sql_text,state,trx_id from v$sessions where trx_id in('6234','6227');
(上图的id应该是6234和6227),如果不开第三个会话那么就看不到update语句,只能看到 select sess_id,sql_text,state,trx_id from v$sessions where trx_id in('6234','6227');
这时执行表结构的语句时会报错锁超时
并且这时新开会话编写sql语句会一直等待上一个事务结束并且不会执行。
找到session_id后使用sp_close_session(session_id)关闭会话
sp_close_session(139843335255648)
也可以在该会话下提交或回滚事务,锁自然会被释放,阻塞解决。
有关技术方面交流请关注社区:达梦数据库 - 新一代大型通用关系型数据库 | 达梦在线服务平台