本文目录导读:

查看当前会话/全局的隔离级别设置,以及监控实际运行中的事务使用了什么隔离级别(因为某些数据库允许在事务级别覆盖默认设置)。
以下是针对主流数据库(MySQL、PostgreSQL、Oracle、SQL Server)的具体监控方法。
MySQL
MySQL 支持 READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ(默认), SERIALIZABLE。
查看当前隔离级别
-
查看当前会话 (Session) 的隔离级别:
SELECT @@transaction_isolation; -- 或旧版语法: SELECT @@tx_isolation;
-
查看全局 (Global) 的隔离级别:
SELECT @@global.transaction_isolation; SELECT @@global.tx_isolation;
监控正在运行的事务的隔离级别
这是最关键的,因为应用程序可能通过 SET TRANSACTION ISOLATION LEVEL ... 动态修改。
-
查询
information_schema.INNODB_TRX表:SELECT trx_id, trx_mysql_thread_id, -- 对应 PROCESSLIST ID trx_isolation_level, -- 这就是当前事务的隔离级别 trx_started, trx_state, trx_rows_locked, trx_lock_structs FROM information_schema.INNODB_TRX;trx_isolation_level会显示READ UNCOMMITTED,READ COMMITTED,REPEATABLE READ或SERIALIZABLE。- 场景:当需要排查某个长事务是否使用了过高的隔离级别(如 Serializable)导致锁冲突时,这个方法非常有效。
-
与
PERFORMANCE_SCHEMA结合(更详细):-- 查看当前活跃会话中正在执行的语句及其隔离级别 SELECT ps.id AS connection_id, ps.user, ps.host, ps.db, ps.command, ps.time, ps.state, it.trx_isolation_level, ps.info AS current_query FROM performance_schema.threads th JOIN information_schema.PROCESSLIST ps ON th.processlist_id = ps.id LEFT JOIN information_schema.INNODB_TRX it ON th.processlist_id = it.trx_mysql_thread_id WHERE ps.command != 'Sleep';
PostgreSQL
PostgreSQL 支持 READ UNCOMMITTED(实际被当作 READ COMMITTED 处理), READ COMMITTED(默认), REPEATABLE READ, SERIALIZABLE。
查看当前隔离级别
-- 查看当前会话的事务隔离级别 SHOW transaction_isolation; -- 查看当前会话的默认设置(来自配置文件或客户端设置) SHOW default_transaction_isolation;
监控正在运行的事务的隔离级别
-
使用
pg_stat_activity:PostgreSQL 的
pg_stat_activity视图并不直接显示当前运行的事务的隔离级别,但可以通过相关视图间接获取。-- 查看活跃的后端进程,并尝试关联事务信息 SELECT pid, datname, usename, application_name, client_addr, state, query_start, query, -- 通过系统函数获取事务隔离级别(如果当前在事务块内) case when query like 'START TRANSACTION%' or query like 'BEGIN%' then 'CHECK SESSION' else 'N/A' end as isolation_note FROM pg_stat_activity WHERE state = 'active' OR state = 'idle in transaction';注意:PostgreSQL 不像 MySQL 那样有一个可以直接查出每个事务隔离级别的系统表,更常见的做法是 从应用日志中获取,或者主动查询正在运行的会话的设置。
-
查询特定会话的隔离级别(需要知道 PID):
-- 假设要查 PID 为 12345 的会话 SELECT pg_catalog.current_setting('transaction_isolation') FROM pg_stat_activity WHERE pid = 12345; -
启用事务日志(生产环境慎用,有性能开销): 修改
postgresql.conf中的log_line_prefix包含%x(事务ID),并设置log_statement = 'mod'或log_min_duration_statement,可以在日志中追踪事务行为。
Oracle
Oracle 有两个主要的隔离级别:READ COMMITTED(默认)和 SERIALIZABLE,以及只读模式。
查看当前会话的隔离级别
-- 查看当前会话
SELECT sys_context('USERENV', 'ISOLATION_LEVEL') AS isolation_level FROM dual;
-- 返回: SERIALIZABLE 或 READ COMMITTED
监控正在运行的事务的隔离级别
-
查询
V$TRANSACTION视图:SELECT t.addr, t.xidusn, t.xidslot, t.xidsqn, t.used_ublk, t.log_io, t.phy_io, t.status, t.start_time, -- 这里是重点:隔离级别 t.space, t.recursive, t.noundo, t.status7 FROM v$transaction t;t.space字段:表示事务是否为SERIALIZABLE模式。'YES'代表 Serializable,'NO'代表 Read Committed。- 更直观的查询:
SELECT s.sid, s.serial#, s.username, t.start_time, DECODE(BITAND(t.flag, 256), 0, 'READ COMMITTED', 'SERIALIZABLE') AS isolation_level FROM v$session s JOIN v$transaction t ON s.saddr = t.ses_addr WHERE s.username IS NOT NULL;t.flag的第8位(256)标识是否为 Serializable 事务。
SQL Server
SQL Server 支持 READ UNCOMMITTED, READ COMMITTED(默认, 取决于 READ_COMMITTED_SNAPSHOT 设置), REPEATABLE READ, SERIALIZABLE, SNAPSHOT。
查看当前会话的隔离级别
-- 查看当前会话
SELECT CASE transaction_isolation_level
WHEN 0 THEN 'Unspecified'
WHEN 1 THEN 'READ UNCOMMITTED'
WHEN 2 THEN 'READ COMMITTED'
WHEN 3 THEN 'REPEATABLE READ'
WHEN 4 THEN 'SERIALIZABLE'
WHEN 5 THEN 'SNAPSHOT'
END AS ISOLATION_LEVEL
FROM sys.dm_exec_sessions
WHERE session_id = @@SPID;
监控所有正在运行的事务的隔离级别
-
查询
sys.dm_exec_sessions:SELECT session_id, login_name, host_name, program_name, status, CASE transaction_isolation_level WHEN 0 THEN 'Unspecified' WHEN 1 THEN 'READ UNCOMMITTED' WHEN 2 THEN 'READ COMMITTED' WHEN 3 THEN 'REPEATABLE READ' WHEN 4 THEN 'SERIALIZABLE' WHEN 5 THEN 'SNAPSHOT' END AS isolation_level, last_request_start_time, reads, writes FROM sys.dm_exec_sessions WHERE session_id > 50 -- 排除系统会话 AND is_user_process = 1; -
查询
sys.dm_tran_active_transactions(更深入):如果需要查看事务与锁的关联:
SELECT t.transaction_id, t.name, t.transaction_begin_time, t.transaction_type, t.transaction_state, s.session_id, s.isolation_level_desc FROM sys.dm_tran_active_transactions t JOIN sys.dm_tran_session_transactions st ON t.transaction_id = st.transaction_id JOIN sys.dm_exec_sessions s ON st.session_id = s.session_id;
通用思路(适用于所有数据库)
-
从应用层监控:
- 在 ORM(如 Hibernate, Entity Framework, MyBatis)的日志中,通常会打印隔离级别设置。
- 在连接池(如 HikariCP, Druid)的配置中,可以启用 SQL 拦截器来记录每条 SQL 执行的上下文,包括隔离级别变更命令(如
SET TRANSACTION ISOLATION LEVEL ...)。
-
使用数据库性能分析工具:
- 大多数云数据库(如 AWS RDS, Azure SQL, 阿里云 RDS)都提供了性能洞察(Performance Insights)或审计日志,可以直接筛选包含
ISOLATION LEVEL的 SQL 语句。 - 使用方案级工具,如 PT-Query-Digest(Percona Toolkit)分析慢查询日志。
- 大多数云数据库(如 AWS RDS, Azure SQL, 阿里云 RDS)都提供了性能洞察(Performance Insights)或审计日志,可以直接筛选包含
-
启用通用日志(生产环境慎用):
- 将
general_log(MySQL)或log_statement(PG)临时开启,grep 包含ISOLATION LEVEL或transaction_isolation的日志。
- 将
总结建议
- 日常巡检:执行
SELECT @@transaction_isolation;(MySQL)或查询sys.dm_exec_sessions(SQL Server)即可获取默认设置。 - 问题排查(例如死锁或锁等待):
- MySQL:首选查询
INFORMATION_SCHEMA.INNODB_TRX,trx_isolation_level字段最直接。 - Oracle:使用
V$TRANSACTION的flag字段判断。 - SQL Server:使用
sys.dm_exec_sessions的transaction_isolation_level字段。 - PostgreSQL:比较麻烦,建议优先从应用日志或直接
SELECT current_setting('transaction_isolation')查询特定会话。
- MySQL:首选查询
如果你能告诉我你使用的是哪种数据库以及你想监控的具体场景(如死锁分析、性能调优、合规审计),我可以给出更针对性的命令。