确定当前事务的隔离级别
Posted DBA随笔
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了确定当前事务的隔离级别相关的知识,希望对你有一定的参考价值。
May,2019
事务的隔离级别
事务是mysql的Innodb存储引擎比较大的亮点,大家对事务的隔离级别肯定都不陌生,那么如何查看当前事务的隔离级别呢?这个方法可能大家也知道,不就是查看当前的transaction_isolation变量么?下面我们分三个部分给说说这个修改隔离级别的操作:
1、修改全局隔离级别(set global trx_isolation)
操作如下:
session 1
1##查看全局隔离级别
2mysql yeyztest 21:28:09>>select @@global.tx_isolation;
3+-----------------------+
4| @@global.tx_isolation |
5+-----------------------+
6| READ-COMMITTED |
7+-----------------------+
81 row in set (0.00 sec)
9
10##查看当前回话的隔离级别
11mysql yeyztest 21:28:42>>select @@session.tx_isolation;
12+------------------------+
13| @@session.tx_isolation |
14+------------------------+
15| READ-COMMITTED |
16+------------------------+
171 row in set (0.00 sec)
18
19mysql yeyztest 21:28:50>>select @@tx_isolation;
20+----------------+
21| @@tx_isolation |
22+----------------+
23| READ-COMMITTED |
24+----------------+
251 row in set (0.00 sec)
此时我们在另外一个session 2上面修改全局的隔离级别,然后再在回话1上面查看隔离级别。步骤如下:
SESSION 2:
1##修改全局隔离级别
2mysql yeyztest 21:37:07>>set global transaction isolation level repeatable read;
3Query OK, 0 rows affected (0.00 sec)
然后我们再看session 1的结果,如下:
1mysql yeyztest 21:30:16>>select @@global.tx_isolation;
2+-----------------------+
3| @@global.tx_isolation |
4+-----------------------+
5| REPEATABLE-READ |
6+-----------------------+
71 row in set (0.00 sec)
8
9mysql yeyztest 21:37:42>>select @@session.tx_isolation;
10+------------------------+
11| @@session.tx_isolation |
12+------------------------+
13| READ-COMMITTED |
14+------------------------+
151 row in set (0.00 sec)
说明修改了全局隔离级别并不会影响当前回话session 1的隔离级别,当我们退出当前回话,再次进入的时候,可以发现,当前session 1的隔离级别也变成了RR,如下:
session 1:
1mysql (none) 21:43:44>>select @@global.tx_isolation;
2+-----------------------+
3| @@global.tx_isolation |
4+-----------------------+
5| REPEATABLE-READ |
6+-----------------------+
71 row in set (0.00 sec)
8
9mysql (none) 21:43:46>>select @@session.tx_isolation;
10+------------------------+
11| @@session.tx_isolation |
12+------------------------+
13| REPEATABLE-READ |
14+------------------------+
151 row in set (0.00 sec)
2、修改当前回话的隔离级别(set session tx_isolation)
在这种情况下,我们在session 1上面使用set session transaction isolation的方法改变session 1的隔离级别,如下:
1mysql 21:43:46>>select @@session.tx_isolation;
2+------------------------+
3| @@session.tx_isolation |
4+------------------------+
5| REPEATABLE-READ |
6+------------------------+
71 row in set (0.00 sec)
8
9mysql 21:48:43>>set session transaction isolation level read uncommitted;
10Query OK, 0 rows affected (0.00 sec)
11
12mysql 21:49:21>>select @@session.tx_isolation;
13+------------------------+
14| @@session.tx_isolation |
15+------------------------+
16| READ-UNCOMMITTED |
17+------------------------+
181 row in set (0.00 sec)
可见当我们使用set session 的方法改变隔离级别的时候,直接会生效。
3、修改下一个事务的隔离级别(set trx_isolation)
再来看第三种情况,在上述修改隔离级别的基础上,我们不加session关键字,看看有什么区别:
1mysql--dba_admin@127.0.0.1:(none) 21:51:35>>select @@session.tx_isolation;
2+------------------------+
3| @@session.tx_isolation |
4+------------------------+
5| READ-UNCOMMITTED |
6+------------------------+
71 row in set (0.00 sec)
8
9mysql--dba_admin@127.0.0.1:(none) 21:51:47>>set transaction isolation level read committed;
10Query OK, 0 rows affected (0.00 sec)
11
12mysql--dba_admin@127.0.0.1:(none) 21:52:00>>select @@session.tx_isolation;
13+------------------------+
14| @@session.tx_isolation |
15+------------------------+
16| READ-UNCOMMITTED |
17+------------------------+
181 row in set (0.00 sec)
我们使用不含session和global的语句将隔离级别改成了read committed,再次查看,看到的结果是read-uncommitted,貌似是没有修改成功,但是别着急,接着做一个试验,我们在session 1上开启一个事务,然后在session 2上查看当前的隔离级别:
session 1:
1mysql 21:53:27>>begin;
2Query OK, 0 rows affected (0.00 sec)
3
4mysql 21:55:10>>select * from yeyztest.slowquery_custom where id=1 for update;
5Empty set (0.00 sec)
session 2:
这里需要注意,session 2上我们如何查询当前session 1中事务的隔离级别呢?可以使用information_schema,这个数据库里面有一个innodb_trx表,这个表的内容就是当前执行的事务的隔离级别:
1mysql 21:55:46>>select * from information_schema.innodb_trxG
2*************************** 1. row ***************************
3 trx_id: 1178769
4 trx_state: RUNNING
5 trx_started: 2019-05-18 21:55:39
6 trx_requested_lock_id: NULL
7 trx_wait_started: NULL
8 trx_weight: 1
9 trx_mysql_thread_id: 3336333
10 trx_query: NULL
11 trx_operation_state: NULL
12 trx_tables_in_use: 0
13 trx_tables_locked: 1
14 trx_lock_structs: 1
15 trx_lock_memory_bytes: 1136
16 trx_rows_locked: 0
17 trx_rows_modified: 0
18 trx_concurrency_tickets: 0
19 trx_isolation_level: READ COMMITTED
20 trx_unique_checks: 1
21 trx_foreign_key_checks: 1
22trx_last_foreign_key_error: NULL
23 trx_adaptive_hash_latched: 0
24 trx_adaptive_hash_timeout: 0
25 trx_is_read_only: 0
26trx_autocommit_non_locking: 0
271 row in set (0.00 sec)
看到了么,这里的值变成了READ COMMITTED,就是说,session 1里面的事务的隔离级别是READ COMMITTED,也就是说,上一步中我们使用set transation isolation语法设置的隔离级别起作用了。
此时我们在session 1上面进行commit操作,然后重新开启一个事务,如下:
session 1:
1mysql 22:04:37>>commit;
2Query OK, 0 rows affected (0.00 sec)
3
4mysql 22:08:40>>begin;
5Query OK, 0 rows affected (0.00 sec)
6
7mysql 22:08:43>>select * from yeyztest.slowquery_custom where id=1 for update;
8Empty set (0.00 sec)
9
10mysql 22:08:46>>
再来看session 2,如下:
1mysql 21:55:48>>select * from information_schema.innodb_trxG
2*************************** 1. row ***************************
3 trx_id: 1178848
4 trx_state: RUNNING
5 trx_started: 2019-05-18 22:08:46
6 trx_requested_lock_id: NULL
7 trx_wait_started: NULL
8 trx_weight: 1
9 trx_mysql_thread_id: 3336333
10 trx_query: NULL
11 trx_operation_state: NULL
12 trx_tables_in_use: 0
13 trx_tables_locked: 1
14 trx_lock_structs: 1
15 trx_lock_memory_bytes: 1136
16 trx_rows_locked: 0
17 trx_rows_modified: 0
18 trx_concurrency_tickets: 0
19 trx_isolation_level: READ UNCOMMITTED
20 trx_unique_checks: 1
21 trx_foreign_key_checks: 1
22trx_last_foreign_key_error: NULL
23 trx_adaptive_hash_latched: 0
24 trx_adaptive_hash_timeout: 0
25 trx_is_read_only: 0
26trx_autocommit_non_locking: 0
271 row in set (0.00 sec)
隔离级别又重新变回了READ UNCOMMITTED,也就是说,使用set transaction isolation的方法,会在下一个事务中生效,而提交了这个事务之后,又会变回原来的隔离级别。
上面的过程,看着比较笼统,简单梳理一下就是:
1、使用set global的方法可以修改全局的隔离级别,修改之后就立即生效;
2、使用set session的方法可以修改当前回话的隔离级别,修改之后立即生效;
3、使用set trx_isolation的方法,不加session和global参数,用来修改下一个事务的隔离级别,当下一个事务提交之后,隔离级别又会变成原来的样子。
4、我们可以通过查询information_schema.innodb_trx表中的记录来查看当前的隔离级别是什么。
以上是关于确定当前事务的隔离级别的主要内容,如果未能解决你的问题,请参考以下文章