MySQL autocommit探究

-- 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,即隔离性。

MySQL autocommit探究

相关推荐