在数据库中一般只有DML操作不提交(或回滚)才会遇到阻塞问题,但是在使用过程中有阻塞发现引起阻塞的SQL为select,但实际上select并不会引起阻塞,其实就是一个会话执行完update又执行select且没有提交或回滚导致的。下面还原一下这种情况。
1.创建一张测试表:
CREATE TABLE "SYSDBA"."T1"
(
"ID" INT,
"FD_TIME" VARCHAR2(50));
insert into t1 values(1,'first');
insert into t1 values(3,'third');
commit;
2.在会话1中更新一条数据不提交:
update t1 set id=2 where id=1;
3.在会话2中更新同一条数据,此时会发现该条SQL一直处于执行状态。这是正常的。查询引起阻塞的原因也是上一条update未提交或回滚导致第二条update阻塞。
-----查询阻塞信息:
SELECT SYSDATE STATTIME,
DATEDIFF(SS, S1.LAST_SEND_TIME, SYSDATE) SS,
'被阻塞的信息' WT,
S1.SESS_ID WT_SESS_ID,
S1.SQL_TEXT WT_SQL_TEXT,
S1.STATE WT_STATE,
S1.TRX_ID WTTRX_ID,
S1.USER_NAME WT_USER_NAME,
S1.CLNT_IP WT_CLNT_IP,
S1.APPNAME WT_APPNAME,
S1.LAST_SEND_TIME WT_LAST_SENDTIME,
'引起阻的信息' FM,
S2.SESS_ID FM_SESS_ID,
S2.SQL_TEXT FM_SQL_TEXT,
S2.STATE FM_STATE,
S2.TRX_ID FM_TRX_ID,
S2.USER_NAME FM_USER_NAME,
S2.CLNT_IP FM_CLNT_IP,
S2.APPNAME FM_APPNAME,
S2.LAST_SEND_TIME FM_LAST_SEND_TIME
from v$sessions s1,
v$sessions s2,
v$trxwait w
where s1.trx_id = w.id
and s2.trx_id = w.wait_for_id;
4.此时在会话1中在不提交不回滚的情况下,再执行一条select语句,此阻塞信息就变成了select相关SQL。
5.解决以上阻塞只能是将第一个会话的update进行提交或回滚或将会话杀死才能解决该阻塞问题。
注:因此在达梦数据库中如果有dml先关操作一定要进行commit或rollback.避免产生阻塞。
6.下面是一些关联关系和排查视图。
1)查询出的相关事务号
2)查询dba_objects与v$lock视图间的事务关系。
select * from dba_objects where owner='模式名' AND OBJECT_NAME='表名';