Ade*_*lin 5 mysql transactions isolation-level
我目前正在尝试阅读MySQL High Performance MySQL,第二版,以了解MySQL中的事务隔离。
这是他们对这两个事务隔离级别的解释。
读已提交
大多数数据库系统(而不是MySQL!)的默认隔离级别是READ COMMITTED。它满足了先前使用的隔离的简单定义:事务将仅看到事务在开始时已经提交的那些更改,并且其他更改直到提交后才对其他人可见。此级别仍允许进行不可重复的读取。这意味着您可以两次运行同一条语句并查看不同的数据。
可重复读取
REPEATABLE READ解决了READ UNCOMMITTED允许的问题。它保证了事务读取的任何行在同一事务的后续读取中都将“看起来相同”,但是从理论上讲,它仍然存在另一个棘手的问题:幻像读取。简而言之,当您选择某一行范围时,如果另一个事务将新行插入该行中,然后再次选择相同的范围,则可能发生幻读。您将看到新的“幻像”行。InnoDB和Falcon通过多版本并发控制解决了幻象读取问题,我们将在本章稍后解释。可重复读取是MySQL的默认事务隔离级别。InnoDB和Falcon存储引擎遵循此设置,您将在第6章中学习如何更改。其他一些存储引擎也可以进行更改,但是选择取决于该引擎。
问题:
1-在READ COMMITTED中,如果此隔离级别表示事务只能看到其他事务所提交的更改,那么在同一事务期间如果运行相同的语句,您会看到不同的结果怎么回事?这是否意味着以下内容?
START TRANSACTION;
SELECT balance FROM checking WHERE customer_id = 10233276;
UPDATE checking SET balance = balance - 200.00 WHERE customer_id = 10233276;
# >>> NEXT I MUST SEE THE NEW BALANCE, OR I AM WRONG ?
SELECT balance FROM checking WHERE customer_id = 10233276;
COMMIT;
Run Code Online (Sandbox Code Playgroud)
2-在“可重复读取”中,如果此隔离级别允许幻像读取,那么它如何保证事务读取的任何行在后续读取中都“看起来相同”?幻象阅读是否驳斥了该级别的保证?
http://ronaldbradford.com/blog/understanding-mysql-innodb-transaction-isolation-2009-09-24/
可重复阅读
第 1 节:
MariaDB [test]> DROP TABLE IF EXISTS transaction_test;
Query OK, 0 rows affected (0.22 sec)
MariaDB [test]> CREATE TABLE transaction_test(
-> id INT UNSIGNED NOT NULL AUTO_INCREMENT,
-> val VARCHAR(20) NOT NULL,
-> created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
-> PRIMARY KEY(id)
-> ) ENGINE=InnoDB DEFAULT CHARSET latin1;
Query OK, 0 rows affected (0.29 sec)
MariaDB [test]>
MariaDB [test]> INSERT INTO transaction_test(val) VALUES ('a'),('b'),('c');
Query OK, 3 rows affected (0.08 sec)
Records: 3 Duplicates: 0 Warnings: 0
MariaDB [test]> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
MariaDB [test]> SELECT * FROM transaction_test;
+----+-----+---------------------+
| id | val | created |
+----+-----+---------------------+
| 1 | a | 2016-04-01 10:09:33 |
| 2 | b | 2016-04-01 10:09:33 |
| 3 | c | 2016-04-01 10:09:33 |
+----+-----+---------------------+
3 rows in set (0.00 sec)
MariaDB [test]> select sleep(50);
Run Code Online (Sandbox Code Playgroud)
然后 user2 运行下一个代码:
MariaDB [test]> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
MariaDB [test]> INSERT INTO transaction_test(val) VALUES ('x'),('y'),('z');
commit;
Run Code Online (Sandbox Code Playgroud)
然后用户 1
MariaDB [test]> SELECT * FROM transaction_test;
+----+-----+---------------------+
| id | val | created |
+----+-----+---------------------+
| 1 | a | 2016-04-01 10:09:33 |
| 2 | b | 2016-04-01 10:09:33 |
| 3 | c | 2016-04-01 10:09:33 |
+----+-----+---------------------+
3 rows in set (0.00 sec)
MariaDB [test]>
Run Code Online (Sandbox Code Playgroud)
读提交
用户 1
SET SESSION tx_isolation='READ-COMMITTED';
TRUNCATE TABLE transaction_test;
INSERT INTO transaction_test(val) VALUES ('a'),('b'),('c');
MariaDB [test]> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
MariaDB [test]> select sleep(60);
Run Code Online (Sandbox Code Playgroud)
然后 user2 运行下一个代码:
MariaDB [test]> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
MariaDB [test]> INSERT INTO transaction_test(val) VALUES ('x'),('y'),('zwfwfw');
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
MariaDB [test]> commit;
Run Code Online (Sandbox Code Playgroud)
然后 user1 完成查询:
MariaDB [test]> SELECT * FROM transaction_test;
+----+--------+---------------------+
| id | val | created |
+----+--------+---------------------+
| 1 | a | 2016-04-01 10:28:08 |
| 2 | b | 2016-04-01 10:28:08 |
| 3 | c | 2016-04-01 10:28:08 |
| 4 | x | 2016-04-01 10:29:00 |
| 5 |
y | 2016-04-01 10:29:00 |
| 6 | zwfwfw | 2016-04-01 10:29:00 |
+----+--------+---------------------+
6 rows in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)