MySQL autocommit探究

原创
2018/09/19 23:28
阅读数 243
-- sessionA:tx_isolation=REPEATABLE-READ
mysql> select connection_id();
+-----------------+
| connection_id() |
+-----------------+
|              28 |
+-----------------+
1 row in set (0.00 sec)

mysql> show variables like '%autocomm%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | OFF   |
+---------------+-------+
1 row in set, 1 warning (0.00 sec)

mysql> select * from a;
+----+
| id |
+----+
|  1 |
+----+
1 row in set (0.00 sec)

mysql> select * from a;
Empty set (0.00 sec)

-- sessionB:tx_isolation=REPEATABLE-READ(注意这里已经是另一个session了!sessionB!)
mysql> select connection_id();
+-----------------+
| connection_id() |
+-----------------+
|              29 |
+-----------------+
1 row in set (0.00 sec)

mysql> show variables like '%autocomm%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | OFF   |
+---------------+-------+
1 row in set, 1 warning (0.00 sec)

mysql> select * from a;
+----+
| id |
+----+
|  1 |
+----+
1 row in set (0.00 sec)

sessionA把数据删掉之后,sessionA就算此时没有commit,在sessionA中再次查询,也是查询不到数据的。(废话,因为已经删掉了嘛!)

那么问题1来了,此时在sessionB中是否能查询出id=1的这条数据呢?

ok,如果在sessionA执行一下commit;

-- sessionA
mysql> select connection_id();
+-----------------+
| connection_id() |
+-----------------+
|              28 |
+-----------------+
1 row in set (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.01 sec)

那此时问题2来了,sessionB执行select * from a;是否能查询到id=1的数据呢?

 

 

 

 

 

 

 

 

 

答案:

问题1:可以查到id=1的数据。

        因为当前tx_isolation=REPEATALBE-READ,所以在sessionA中未提交的事务,在其他事务中,是看不到的。(而如果tx_isolation=READ UNCOMMIT,则可以看到未提交事务的修改。)

问题2:也可以查到id=1的数据。下面是证据:

-- sessionB
mysql> select connection_id();
+-----------------+
| connection_id() |
+-----------------+
|              29 |
+-----------------+
1 row in set (0.00 sec)

mysql> select * from a;
+----+
| id |
+----+
|  1 |
+----+
1 row in set (0.00 sec)

原因下面说,先来说一下此时如何在sessionB中看到的数据和sessionA一致呢?只需要在sessionB中commit;一下就ok了。

-- sessionB
mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from a;
Empty set (0.00 sec)

ok,这里说一下个人理解(如有错误,请留言提出)

        由于autocommit=0,此时事务并不会自动提交,可以理解为在开启sessionB的时候,就默认开启了一个事务(start transaction;)。

        而在sessionB中执行commit,可以理解为commit是为了让sessionB的事务结束,因为在tx_isolation=REPEATABLE-READ的隔离级别下,在一个不提交或者不rollback的事务中,无法看到其他事务就算是commit的修改。这也是满足了ACID中的I,即隔离性。

 

 

ok。如果对这些知识不太了解的小伙伴,可以系统地阅读《MySQL技术内幕-InnoDB存储引擎》姜承尧·著

ok。Good Night!

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
1
分享
返回顶部
顶部