-- 以 SYSDBA 登录
-- 清理环境
DROP TABLE IF EXISTS T_ISO;
CREATE TABLE T_ISO(ID INT PRIMARY KEY, VAL INT);
INSERT INTO T_ISO VALUES(1,100);
COMMIT;
-- 1 读提交(READ COMMITTED) --现象:会话 B 只能读到会话 A 已提交 的数据,但同一事务内重复读可能不一致(不可重复读)。 -- 会话 A SET TRANSACTION ISOLATION LEVEL READ COMMITTED; UPDATE T_ISO SET VAL=200 WHERE ID=1; -- 不提交 SELECT * FROM T_ISO WHERE ID=1; -- 看到 200 -- 会话 B(新开窗口) SET TRANSACTION ISOLATION LEVEL READ COMMITTED; SELECT * FROM T_ISO WHERE ID=1; -- 仍看到 100(脏读被阻止) --上面参考图1 -- 回到会话 A COMMIT; -- 会话 B 再查 SELECT * FROM T_ISO WHERE ID=1; -- 看到 200(不可重复读出现) --上面参考 图2
-- 2 串行化(SERIALIZABLE) --只有在写-写冲突时才会出现锁等待 --现象:会话 B 的查询不会阻塞/写入会被阻塞,直到会话 A 提交 -- 会话 A SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; UPDATE T_ISO SET VAL=300 WHERE ID=1; -- 不提交 -- 会话 B SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; SELECT * FROM T_ISO WHERE ID=1; -- 不被阻塞 -- 会话 B 立即返回结果,看到 300 -- 会话 B SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; UPDATE T_ISO SET VAL=301 WHERE ID=1; -- 此时才会被阻塞,直到 A commit/rollback --参考图3,图4,图5
-- 3读未提交(READ UNCOMMITTED)
--现象:会话 B 可脏读会话 A 未提交的修改;也可用 SELECT ISO WITH UR 临时脏读。
-- 会话 A
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
UPDATE T_ISO SET VAL=400 WHERE ID=1; -- 不提交
-- 会话 B
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * FROM T_ISO WHERE ID=1; -- 直接看到 400(脏读)
-- 或者会话 B 不改隔离级,仅临时脏读
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
SELECT * FROM T_ISO WHERE ID=1 WITH UR; -- 同样看到 400,语句级脏读
-- 回滚 A 观察脏读消失
ROLLBACK;
--参考图6,图7
-- 4只读事务(READ ONLY) --现象:事务内只能做 SELECT,任何 DML/DDL 都会报错;可与其他读写事务并发。 -- 会话 A SET TRANSACTION READ ONLY; SELECT * FROM T_ISO WHERE ID=1; -- 正常查询 UPDATE T_ISO SET VAL=500 WHERE ID=1; -- 立即报错:仅允许只读事务执行查询语句 -- 会话 B(普通读写事务) UPDATE T_ISO SET VAL=600 WHERE ID=1; COMMIT; -- 会话 A 再次查询 SELECT * FROM T_ISO WHERE ID=1; -- 看到 600(读提交语义,仍只读) --参考图8,图9,图10
-- 3 查询当前会话的事务状态信息
SELECT
CASE(ISOLATION)
WHEN 0 THEN '读未提交'
WHEN 1 THEN '读提交'
WHEN 2 THEN '可重复读'
WHEN 3 THEN '串行化'
END AS _ISOLATION,
S.SQL_TEXT,
T.*
FROM
V$TRX T,
V$SESSIONS S
WHERE
T.SESS_ID = S.SESS_ID
文章
阅读量
获赞