Mysqlトランザクションの独立性レベル

6531 ワード

開発の仕事で私たちは事務に使いますが、事務は何種類あるか知っていますか.
MYSQL規格では、トランザクションの内外でどのような変更が可視であるか、非可視であるかを定義する4つの独立性レベルが定義されています.低い独立性レベルは、一般的に、より高い同時処理をサポートし、システムオーバーヘッドを低減します.独立性レベルは低~高:Read Uncommitted**Read Uncommitted(コミットされていないコンテンツの読み取り)**
この独立性レベルでは、すべてのトランザクションに対して、他のコミットされていないトランザクションの実行結果が表示されます.この独立性レベルは、他のレベルよりもパフォーマンスが優れていないため、実際のアプリケーションではあまり使用されません.コミットされていないデータを読み取ることをダーティリード(Dirty Read)ともいう.
[  A]:

mysql> set GLOBAL tx_isolation='READ-UNCOMMITTED';
Query OK, 0 rows affected (0.00 sec)

mysql> quit;
Bye

[root@vagrant-centos65 ~]# mysql -uroot -pxxxx(    )

mysql> SELECT @@tx_isolation;
+------------------+
| @@tx_isolation   |
+------------------+
| READ-UNCOMMITTED |
+------------------+
1 row in set (0.00 sec)

mysql> use test;
Database changed
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from user;
+----+------+
| id | name |
+----+------+
|  1 | a    |
|  2 | b    |
+----+------+
2 rows in set (0.00 sec)

[  B]:
mysql> select @@tx_isolation;
+------------------+
| @@tx_isolation   |
+------------------+
| READ-UNCOMMITTED |
+------------------+
1 row in set (0.00 sec)

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into test.user values (3, 'c');
Query OK, 1 row affected (0.00 sec)

mysql> select * from user;
+----+------+
| id | name |
+----+------+
|  1 | a    |
|  2 | b    |
|  3 | c    |
+----+------+
3 rows in set (0.00 sec)

//    ,  B  commit;

[  A]:
mysql> select * from user ;
+----+------+
| id | name |
+----+------+
|  1 | a    |
|  2 | b    |
|  3 | c    |
+----+------+
3 rows in set (0.00 sec)


**Read Committed(コミット内容の読み取り)**
これは、ほとんどのデータベース・システムのデフォルトの独立性レベルです(ただし、MySQLのデフォルトではありません).独立性の簡単な定義を満たしています.1つのトランザクションでは、トランザクションにコミットされた変更しか表示されません.この独立性レベルは、同じトランザクションの他のインスタンスがインスタンス処理の間に新しいcommitを返す可能性があるため、同じselectが異なる結果を返す可能性があるため、いわゆる重複不可能読み出し(NonrepeatableRead)もサポートします.
[  A]:

mysql> SET GLOBAL tx_isolation='READ-COMMITTED';
Query OK, 0 rows affected (0.00 sec)

mysql> quit;
Bye

[root@vagrant-centos65 ~]# mysql -uroot -pxxxx(    )

mysql> SELECT @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| READ-COMMITTED |
+----------------+
1 row in set (0.00 sec)

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from test.user;
+----+------+
| id | name |
+----+------+
|  1 | a    |
|  2 | b    |
+----+------+
2 rows in set (0.00 sec)

[  B]:

mysql> SELECT @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| READ-COMMITTED |
+----------------+
1 row in set (0.00 sec)

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from test.user;
+----+------+
| id | name |
+----+------+
|  1 | a    |
|  2 | b    |
+----+------+
2 rows in set (0.00 sec)

mysql> delete from test.user where id=1;
Query OK, 1 row affected (0.00 sec)

mysql> select * from test.user;
+----+------+
| id | name |
+----+------+
|  2 | b    |
+----+------+
1 row in set (0.00 sec)

[  A]:

mysql> select * from test.user;
+----+------+
| id | name |
+----+------+
|  1 | a    |
|  2 | b    |
+----+------+
2 rows in set (0.00 sec)

[  B]:

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

[  A]:

mysql> select * from test.user;
+----+------+
| id | name |
+----+------+
|  2 | b    |
+----+------+
1 row in set (0.00 sec)


**Repeatable Read(再読み込み可能)**
これはMySQLのデフォルトのトランザクション独立性レベルで、同じトランザクションの複数のインスタンスがデータを同時に読み込むときに同じデータ行が表示されることを保証します.しかし、理論的には、幻読(Phantom Read)というもう一つの厄介な問題を引き起こす.簡単に言えば、幻読みとは、ユーザがある範囲のデータ行を読み取ると、別のトランザクションがその範囲内に新しい行を挿入し、ユーザがその範囲のデータ行を読み取ると、新しい「幻」行が発見されることを意味する.InnoDBとFalconストレージエンジンは、この問題をマルチバージョン同時制御(MVCC,Multiversion Concurrency Control)メカニズムによって解決した.
[  A]:

mysql> SET GLOBAL tx_isolation='REPEATABLE-READ';
Query OK, 0 rows affected (0.00 sec)

mysql> quit;
Bye

[root@vagrant-centos65 ~]# mysql -uroot -pxxxx(    )

mysql> SELECT @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set (0.00 sec)

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

[  B]:

mysql> quit;
Bye

[root@vagrant-centos65 ~]# mysql -uroot -pxxxx(    )

mysql> SELECT @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set (0.00 sec)

mysql> insert into test.user values (4, 'd');
Query OK, 1 row affected (0.00 sec)

mysql> select * from test.user;
+----+------+
| id | name |
+----+------+
|  2 | b    |
|  4 | d    |
+----+------+
2 rows in set (0.00 sec)

[  A]:

mysql> select * from test.user;
+----+------+
| id | name |
+----+------+
|  2 | b    |
+----+------+
1 rows in set (0.00 sec)

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

mysql> select * from test.user;
+----+------+
| id | name |
+----+------+
|  2 | b    |
|  4 | d    |
+----+------+
2 rows in set (0.00 sec)


**Serializable(シーケンス化実行)**
これは、トランザクションのソートを強制することで、互いに衝突しないようにする最も高い独立性レベルです.これにより、ファンタジーの問題を解決します.簡単に言えば、各読み出しデータ行に共有ロックを追加します.このレベルでは、大量のタイムアウト現象とロック競合を引き起こす可能性があります.
[  A]:

mysql> SET GLOBAL tx_isolation='SERIALIZABLE';
Query OK, 0 rows affected (0.00 sec)

mysql> quit;
Bye

[root@vagrant-centos65 ~]# mysql -uroot -pxxxx(    )

mysql> SELECT @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| SERIALIZABLE   |
+----------------+
1 row in set (0.00 sec)

mysql> select * from test.user;
+----+------+
| id | name |
+----+------+
|  2 | b    |
|  4 | d    |
+----+------+
2 rows in set (0.00 sec)

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into test.user values (5, 'e');
Query OK, 1 row affected (0.00 sec)

[  B]:

mysql> quit;
Bye

[root@vagrant-centos65 ~]# mysql -uroot -pxxxx(    )

mysql> SELECT @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| SERIALIZABLE   |
+----------------+
1 row in set (0.00 sec)

mysql> select * from test.user;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

[  A]:

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

[  B]:

mysql> mysql> select * from test.user;
+----+------+
| id | name |
+----+------+
|  2 | b    |
|  4 | d    |
|  5 | e    |
+----+------+
3 rows in set (0.00 sec)

Thanks ~