测试在DM 单机环境下,两个session 更改同一条记录,先更改的会话不提交,导致后面的会话出现等待。
管理员会话:使用管理员创建测试用户
SQL> create user TUSER identified by "Dameng123" default tablespace "DMHR" default index tablespace "DMHR";
SQL> grant "PUBLIC","RESOURCE","SOI","SVI","VTI" to TUSER;
session 1:
./disql tuser/Dameng123
创建测试表
create table TUSER.TAB01
(
ID NUMBER(10, 0) not null ,
NAME VARCHAR2(10),
ADDRESS VARCHAR2(10),
primary key("ID")
);
插入测试数据
SQL> insert into TUSER.TAB01 values(1,'Scott','USA');
SQL> insert into TUSER.TAB01 values(2,'Jason','CN');
SQL> commit;
查询现有数据
SQL> select * from TUSER.TAB01;
行号 ID NAME ADDRESS
---------- -- ----- -------
1 1 Scott USA
2 2 Jason CN
更新一条数据,并不提交
SQL> update TUSER.TAB01 set name='Tony' where id=2;
再次查询现有数据
SQL> select * from TUSER.TAB01;
行号 ID NAME ADDRESS
---------- -- ----- -------
1 1 Scott USA
2 2 Tony CN
session 2
./disql tuser/Dameng123
查询询现有数据
SQL> select * from TUSER.TAB01;
行号 ID NAME ADDRESS
---------- -- ----- -------
1 1 Scott USA
2 2 Jason CN
session 2 更新相同的一条数据
update TUSER.TAB01 set name='Larry' where id=2;
session 2 出现卡顿
管理员会话:使用管理员查看当前session 状态
select * from v$sessions where user_name='TUSER';
10763243816 12 select * from TUSER.TAB01; IDLE 64 1 7 TUSER TUSER
17711400 14 update TUSER.TAB01 set name='Larry' where id=2; ACTIVE 64 1 5 TUSER TUSER
可以看到 session 2 是在执行 update,而session 1 最后一条SQL 是在select 查询。 这个时候很容易造成误解,认为session 1并没有阻塞2。
查询未提交的事务
SQL> select t1.user_name,t1.sess_id,t1.sql_text,t1.state,t1.trx_id,T2.INS_CNT,T2.DEL_CNT,T2.UPD_CNT
from v$sessions t1
join v$trx t2
on t1.trx_id=t2.id
where t1.state='IDLE' AND T2.STATUS='ACTIVE'
user_name sess_id sql_text state trx_id INS_CNT DEL_CNT UPD_CNT
'TUSER' 10763243816 'select * from TUSER.TAB01;' 'IDLE' 166704 0 0 1
可以看到,这个会话10763243816 在session 中是IDLE 状态,但在v$trx 中是ACTIVE 状态,并且有一条更新UPD_CNT 1。
将这个session 手工kill
SP_CLOSE_SESSION(10763243816);
这个时候再检查session 2,已经执行成功,并且用时27分钟左右,说明一直在等待。
SQL> update TUSER.TAB01 set name='Larry' where id=2;
影响行数 1
已用时间: 00:27:16.037. 执行号:1602.
欢迎访问达梦技术分享社区 ECO