前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >确定当前事务的隔离级别

确定当前事务的隔离级别

作者头像
AsiaYe
发布2019-11-06 17:13:07
6500
发布2019-11-06 17:13:07
举报
文章被收录于专栏:DBA随笔
确定当前事务的隔离级别
事务的隔离级别

事务是MySQL的Innodb存储引擎比较大的亮点,大家对事务的隔离级别肯定都不陌生,那么如何查看当前事务的隔离级别呢?这个方法可能大家也知道,不就是查看当前的transaction_isolation变量么?下面我们分三个部分给说说这个修改隔离级别的操作:

1、修改全局隔离级别(set global trx_isolation)

操作如下:

session 1

代码语言:javascript
复制
##查看全局隔离级别
mysql yeyztest 21:28:09>>select @@global.tx_isolation;
+-----------------------+
| @@global.tx_isolation |
+-----------------------+
| READ-COMMITTED        |
+-----------------------+
1 row in set (0.00 sec)

##查看当前回话的隔离级别
mysql yeyztest 21:28:42>>select @@session.tx_isolation;
+------------------------+
| @@session.tx_isolation |
+------------------------+
| READ-COMMITTED         |
+------------------------+
1 row in set (0.00 sec)

mysql yeyztest 21:28:50>>select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| READ-COMMITTED |
+----------------+
1 row in set (0.00 sec)

此时我们在另外一个session 2上面修改全局的隔离级别,然后再在回话1上面查看隔离级别。步骤如下:

SESSION 2:

代码语言:javascript
复制
##修改全局隔离级别
mysql yeyztest 21:37:07>>set global transaction isolation level repeatable read;
Query OK, 0 rows affected (0.00 sec)

然后我们再看session 1的结果,如下:

代码语言:javascript
复制
mysql yeyztest 21:30:16>>select @@global.tx_isolation;
+-----------------------+
| @@global.tx_isolation |
+-----------------------+
| REPEATABLE-READ       |
+-----------------------+
1 row in set (0.00 sec)

mysql yeyztest 21:37:42>>select @@session.tx_isolation;
+------------------------+
| @@session.tx_isolation |
+------------------------+
| READ-COMMITTED         |
+------------------------+
1 row in set (0.00 sec)

说明修改了全局隔离级别并不会影响当前回话session 1的隔离级别,当我们退出当前回话,再次进入的时候,可以发现,当前session 1的隔离级别也变成了RR,如下:

session 1:

代码语言:javascript
复制
mysql (none) 21:43:44>>select @@global.tx_isolation;
+-----------------------+
| @@global.tx_isolation |
+-----------------------+
| REPEATABLE-READ       |
+-----------------------+
1 row in set (0.00 sec)

mysql (none) 21:43:46>>select @@session.tx_isolation;
+------------------------+
| @@session.tx_isolation |
+------------------------+
| REPEATABLE-READ        |
+------------------------+
1 row in set (0.00 sec)

2、修改当前回话的隔离级别(set session tx_isolation)

在这种情况下,我们在session 1上面使用set session transaction isolation的方法改变session 1的隔离级别,如下:

代码语言:javascript
复制
mysql  21:43:46>>select @@session.tx_isolation;
+------------------------+
| @@session.tx_isolation |
+------------------------+
| REPEATABLE-READ        |
+------------------------+
1 row in set (0.00 sec)

mysql  21:48:43>>set session transaction isolation level read uncommitted;
Query OK, 0 rows affected (0.00 sec)

mysql  21:49:21>>select @@session.tx_isolation;
+------------------------+
| @@session.tx_isolation |
+------------------------+
| READ-UNCOMMITTED       |
+------------------------+
1 row in set (0.00 sec)

可见当我们使用set session 的方法改变隔离级别的时候,直接会生效。

3、修改下一个事务的隔离级别(set trx_isolation)

再来看第三种情况,在上述修改隔离级别的基础上,我们不加session关键字,看看有什么区别:

代码语言:javascript
复制
mysql--dba_admin@127.0.0.1:(none) 21:51:35>>select @@session.tx_isolation;
+------------------------+
| @@session.tx_isolation |
+------------------------+
| READ-UNCOMMITTED       |
+------------------------+
1 row in set (0.00 sec)

mysql--dba_admin@127.0.0.1:(none) 21:51:47>>set  transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)

mysql--dba_admin@127.0.0.1:(none) 21:52:00>>select @@session.tx_isolation;
+------------------------+
| @@session.tx_isolation |
+------------------------+
| READ-UNCOMMITTED       |
+------------------------+
1 row in set (0.00 sec)

我们使用不含session和global的语句将隔离级别改成了read committed,再次查看,看到的结果是read-uncommitted,貌似是没有修改成功,但是别着急,接着做一个试验,我们在session 1上开启一个事务,然后在session 2上查看当前的隔离级别:

session 1:

代码语言:javascript
复制
mysql  21:53:27>>begin;
Query OK, 0 rows affected (0.00 sec)

mysql  21:55:10>>select * from yeyztest.slowquery_custom where id=1 for update;
Empty set (0.00 sec)

session 2:

这里需要注意,session 2上我们如何查询当前session 1中事务的隔离级别呢?可以使用information_schema,这个数据库里面有一个innodb_trx表,这个表的内容就是当前执行的事务的隔离级别:

代码语言:javascript
复制
mysql  21:55:46>>select * from information_schema.innodb_trx\G
*************************** 1. row ***************************
                    trx_id: 1178769
                 trx_state: RUNNING
               trx_started: 2019-05-18 21:55:39
     trx_requested_lock_id: NULL
          trx_wait_started: NULL
                trx_weight: 1
       trx_mysql_thread_id: 3336333
                 trx_query: NULL
       trx_operation_state: NULL
         trx_tables_in_use: 0
         trx_tables_locked: 1
          trx_lock_structs: 1
     trx_lock_memory_bytes: 1136
           trx_rows_locked: 0
         trx_rows_modified: 0
   trx_concurrency_tickets: 0
       trx_isolation_level: READ COMMITTED
         trx_unique_checks: 1
    trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
 trx_adaptive_hash_latched: 0
 trx_adaptive_hash_timeout: 0
          trx_is_read_only: 0
trx_autocommit_non_locking: 0
1 row in set (0.00 sec)

看到了么,这里的值变成了READ COMMITTED,就是说,session 1里面的事务的隔离级别是READ COMMITTED,也就是说,上一步中我们使用set transation isolation语法设置的隔离级别起作用了。

此时我们在session 1上面进行commit操作,然后重新开启一个事务,如下:

session 1:

代码语言:javascript
复制
mysql  22:04:37>>commit;
Query OK, 0 rows affected (0.00 sec)

mysql  22:08:40>>begin;
Query OK, 0 rows affected (0.00 sec)

mysql  22:08:43>>select * from yeyztest.slowquery_custom where id=1 for update;
Empty set (0.00 sec)

mysql  22:08:46>>

再来看session 2,如下:

代码语言:javascript
复制
mysql  21:55:48>>select * from information_schema.innodb_trx\G
*************************** 1. row ***************************
                    trx_id: 1178848
                 trx_state: RUNNING
               trx_started: 2019-05-18 22:08:46
     trx_requested_lock_id: NULL
          trx_wait_started: NULL
                trx_weight: 1
       trx_mysql_thread_id: 3336333
                 trx_query: NULL
       trx_operation_state: NULL
         trx_tables_in_use: 0
         trx_tables_locked: 1
          trx_lock_structs: 1
     trx_lock_memory_bytes: 1136
           trx_rows_locked: 0
         trx_rows_modified: 0
   trx_concurrency_tickets: 0
       trx_isolation_level: READ UNCOMMITTED
         trx_unique_checks: 1
    trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
 trx_adaptive_hash_latched: 0
 trx_adaptive_hash_timeout: 0
          trx_is_read_only: 0
trx_autocommit_non_locking: 0
1 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表中的记录来查看当前的隔离级别是什么。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-05-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DBA随笔 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档