Heim  >  Artikel  >  php教程  >  Vier Isolationsstufen von MySQL-Transaktionen

Vier Isolationsstufen von MySQL-Transaktionen

WBOY
WBOYOriginal
2016-08-04 08:56:161044Durchsuche

Wir werden Transaktionen in der Entwicklungsarbeit verwenden. Wissen Sie also, welche Arten von Transaktionen es gibt?
Der MYSQL-Standard definiert vier Arten von Isolationsstufen, die dazu dienen, einzuschränken, welche Änderungen innerhalb und außerhalb der Transaktion sichtbar und welche unsichtbar sind.
Niedrigere Isolationsstufen unterstützen im Allgemeinen eine höhere Parallelität und haben einen geringeren Systemaufwand.
Isolationsstufen von niedrig nach hoch: Nicht festgeschrieben lesen < Wiederholbar lesen <
Uncommitted lesen

Auf dieser Isolationsstufe können alle Transaktionen die Ausführungsergebnisse anderer nicht festgeschriebener Transaktionen sehen.
Diese Isolationsstufe wird in praktischen Anwendungen selten verwendet, da ihre Leistung nicht viel besser ist als die anderer Stufen.
Das Lesen nicht festgeschriebener Daten wird auch als Dirty Read bezeichnet. [窗口A]:<br /> <br /> mysql> set GLOBAL tx_isolation='READ-UNCOMMITTED';<br> Query OK, 0 rows affected (0.00 sec)<br> <br> mysql> quit;<br> Bye<br> <br> [root@vagrant-centos65 ~]# mysql -uroot -pxxxx(重新登录)<br> <br> mysql> SELECT @@tx_isolation;<br> ------------------ <br> | @@tx_isolation   |<br> ------------------ <br> | READ-UNCOMMITTED |<br> ------------------ <br> 1 row in set (0.00 sec)<br> <br> mysql> use test;<br> Database changed<br> mysql> begin;<br> Query OK, 0 rows affected (0.00 sec)<br> <br> mysql> select * from user;<br> ---- ------ <br> | id | name |<br> ---- ------ <br> |  1 | a    |<br> |  2 | b    |<br> ---- ------ <br> 2 rows in set (0.00 sec)<br> <br> [窗口B]:<br> mysql> select @@tx_isolation;<br> ------------------ <br> | @@tx_isolation   |<br> ------------------ <br> | READ-UNCOMMITTED |<br> ------------------ <br> 1 row in set (0.00 sec)<br> <br> mysql> begin;<br> Query OK, 0 rows affected (0.00 sec)<br> <br> mysql> insert into test.user values (3, 'c');<br> Query OK, 1 row affected (0.00 sec)<br> <br> mysql> select * from user;<br> ---- ------ <br> | id | name |<br> ---- ------ <br> |  1 | a    |<br> |  2 | b    |<br> |  3 | c    |<br> ---- ------ <br> 3 rows in set (0.00 sec)<br> <br> //目前为止,窗口B并未commit;<br> <br> [窗口A]:<br> mysql> select * from user ;<br> ---- ------ <br> | id | name |<br> ---- ------ <br> |  1 | a    |<br> |  2 | b    |<br> |  3 | c    |<br> ---- ------ <br> 3 rows in set (0.00 sec)[Fenster A]:<b> </b> mysql> set GLOBAL tx_isolation='READ-UNCOMMITTED';<br> Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)<br> <br> mysql> quit;<br> Tschüss<code class="prettyprint linenums lang-php"> <br> [root@vagrant-centos65 ~]# mysql -uroot -pxxxx (erneut anmelden)<br> <br> mysql> SELECT @@tx_isolation;<br> ---- <br> |. @@tx_isolation |<br> ---- <br> |. READ-UNCOMMITTED |<br> ---- <br> 1 Reihe im Satz (0,00 Sek.)<br> <br> mysql> use test;<br> Datenbank geändert<br> mysql> begin;<br> Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)<br> <br> mysql> select * from user;<br> ---- ------ <br> |. id |. name |<br> ---- ------ <br> |. 1 |. a |<br> |. 2 |. b |<br> ---- ------ <br> 2 Reihen im Satz (0,00 Sek.)<br> <br> [Fenster B]:<br> mysql> select @@tx_isolation;<br> ---- <br> |. @@tx_isolation |<br> ---- <br> |. READ-UNCOMMITTED |<br> ---- <br> 1 Reihe im Satz (0,00 Sek.)<br> <br> mysql> begin;<br> Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)<br> <br> mysql> in test.user-Werte einfügen (3, 'c');<br> Abfrage OK, 1 Zeile betroffen (0,00 Sek.)<br> <br> mysql> select * from user;<br> ---- ------ <br> |. id |. name |<br> ---- ------ <br> |. 1 |. a | |. 2 |. b | |. 3 |. c | ---- ------ 3 Reihen im Satz (0,00 Sek.) //Bisher wurde Fenster B nicht festgeschrieben; [Fenster A]: mysql> select * from user ; ---- ------ |. id |. name | ---- ------ |. 1 |. a | |. 2 |. b | |. 3 |. c | ---- ------ 3 Zeilen im Satz (0,00 Sek.)Read Committed (eingereichten Inhalt lesen) Dies ist die Standardisolationsstufe für die meisten Datenbanksysteme (jedoch nicht die MySQL-Standardeinstellung). Es erfüllt die einfache Definition von Isolation: Eine Transaktion kann nur Änderungen sehen, die von festgeschriebenen Transaktionen vorgenommen wurden. Diese Isolationsstufe unterstützt auch das sogenannte nicht wiederholbare Lesen (NonrepeatableRead), da andere Instanzen derselben Transaktion während der Verarbeitung dieser Instanz möglicherweise neue Commits haben, sodass dieselbe Auswahl möglicherweise unterschiedliche Ergebnisse zurückgibt. [Fenster A]: mysql> SET GLOBAL tx_isolation='READ-COMMITTED'; Abfrage OK, 0 Zeilen betroffen (0,00 Sek.) mysql> quit; Tschüss [root@vagrant-centos65 ~]# mysql -uroot -pxxxx (erneut anmelden) mysql> SELECT @@tx_isolation; ---------------- |. @@tx_isolation | ---------------- |. READ-COMMITTED | ---------------- 1 Reihe im Satz (0,00 Sek.) mysql> begin; Abfrage OK, 0 Zeilen betroffen (0,00 Sek.) mysql> select * from test.user; ---- ------ |. id |. name | ---- ------ |. 1 |. a | |. 2 |. b | ---- ------ 2 Reihen im Satz (0,00 Sek.) [Fenster B]: mysql> SELECT @@tx_isolation; ---------------- |. @@tx_isolation | ---------------- |. READ-COMMITTED | ---------------- 1 Reihe im Satz (0,00 Sek.) mysql> begin; Abfrage OK, 0 Zeilen betroffen (0,00 Sek.) mysql> Wählen Sie * aus test.user;
aus ---- ------
| id | Name |
---- ------
|  1 | a    |
|  2 | b    |
---- ------
2 Zeilen im Satz (0,00 Sek.)

mysql> löschen aus test.user wo id=1;
Abfrage OK, 1 Zeile betroffen (0,00 Sek.)

mysql> Wählen Sie * aus test.user;
aus ---- ------
| id | Name |
---- ------
|  2 | b    |
---- ------
1 Zeile pro Satz (0,00 Sek.)

[窗口A]:

mysql> Wählen Sie * aus test.user;
aus ---- ------
| id | Name |
---- ------
|  1 | a    |
|  2 | b    |
---- ------
2 Zeilen im Satz (0,00 Sek.)

[窗口B]:

mysql> verpflichten;
Abfrage OK, 0 Zeilen betroffen (0,02 Sek.)

[窗口A]:

mysql> Wählen Sie * aus test.user;
aus ---- ------
| id | Name |
---- ------
|  2 | b    |
---- ------
1 Zeile pro Satz (0,00 Sek.)Wiederholbares Lesen(可重读)

这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行.
不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。
简单的说, 幻读指当用户读取某一范围的数据行时, 另一个事务又在该范围内插入了新行, 当用户再读取该范围的数据行时,会发现有新的“幻影“ 行.
InnoDB 和 Falcon 存储引擎通过多版本并发控制( MVCC , Multiversion Concurrency Control )机制解决了该问题。 [窗口 A]: <code class="prettyprint linenums lang-php">[窗口A]:<br> <br> mysql> SET GLOBAL tx_isolation='REPEATABLE-READ';<br> Query OK, 0 rows affected (0.00 sec)<br> <br> mysql> quit;<br> Bye<br> <br> [root@vagrant-centos65 ~]# mysql -uroot -pxxxx(重新登录)<br> <br> mysql> SELECT @@tx_isolation;<br> ----------------- <br> | @@tx_isolation  |<br> ----------------- <br> | REPEATABLE-READ |<br> ----------------- <br> 1 row in set (0.00 sec)<br> <br> mysql> begin;<br> Query OK, 0 rows affected (0.00 sec)<br> <br> [窗口B]:<br> <br> mysql> quit;<br> Bye<br> <br> [root@vagrant-centos65 ~]# mysql -uroot -pxxxx(重新登录)<br> <br> mysql> SELECT @@tx_isolation;<br> ----------------- <br> | @@tx_isolation  |<br> ----------------- <br> | REPEATABLE-READ |<br> ----------------- <br> 1 row in set (0.00 sec)<br> <br> mysql> insert into test.user values (4, 'd');<br> Query OK, 1 row affected (0.00 sec)<br> <br> mysql> select * from test.user;<br> ---- ------ <br> | id | name |<br> ---- ------ <br> |  2 | b    |<br> |  4 | d    |<br> ---- ------ <br> 2 rows in set (0.00 sec)<br> <br> [窗口A]:<br> <br> mysql> select * from test.user;<br> ---- ------ <br> | id | name |<br> ---- ------ <br> |  2 | b    |<br> ---- ------ <br> 1 rows in set (0.00 sec)<br> <br> mysql> commit;<br> Query OK, 0 rows affected (0.00 sec)<br> <br> mysql> select * from test.user;<br> ---- ------ <br> | id | name |<br> ---- ------ <br> |  2 | b    |<br> |  4 | d    |<br> ---- ------ <br> 2 rows in set (0.00 sec) mysql> SET GLOBAL tx_isolation='REPEATABLE-READ'; Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)

mysql> aufhören;
Tschüss [root@vagrant-centos65 ~]# mysql -uroot -pxxxx(重新登录) mysql> SELECT @@tx_isolation; ----------------- | @@tx_isolation  | ----------------- | WIEDERHOLBARES LESEN | ----------------- 1 Zeile pro Satz (0,00 Sek.) mysql> beginnen; Abfrage OK, 0 Zeilen betroffen (0,00 Sek.) [窗口B]: mysql> aufhören; Tschüss [root@vagrant-centos65 ~]# mysql -uroot -pxxxx(重新登录) mysql> SELECT @@tx_isolation; ----------------- | @@tx_isolation  | ----------------- | WIEDERHOLBARES LESEN | ----------------- 1 Zeile pro Satz (0,00 Sek.) mysql> insert in test.user values (4, 'd'); Abfrage OK, 1 Zeile betroffen (0,00 Sek.) mysql> Wählen Sie * aus test.user; aus ---- ------ | id | Name | ---- ------ |  2 | b    | |  4 | d    | ---- ------ 2 Zeilen im Satz (0,00 Sek.) [窗口A]: mysql> Wählen Sie * aus test.user; aus ---- ------ | id | Name | ---- ------ |  2 | b    | ---- ------ 1 Zeilen im Satz (0,00 Sek.) mysql> verpflichten; Abfrage OK, 0 Zeilen betroffen (0,00 Sek.) mysql> Wählen Sie * aus test.user; aus ---- ------ | id | Name | ---- ------ |  2 | b    | |  4 | d    | ---- ------ 2 Zeilen im Satz (0,00 Sek.)Serialisierbar(序列化执行) 这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题.Kurz gesagt, es fügt jeder gelesenen Datenzeile eine gemeinsame Sperre hinzu. Auf dieser Ebene kann es zu zahlreichen Zeitüberschreitungen und Sperrkonflikten kommen. [窗口A]:<br> <br> mysql> SET GLOBAL tx_isolation='SERIALIZABLE';<br> Query OK, 0 rows affected (0.00 sec)<br> <br> mysql> quit;<br> Bye<br> <br> [root@vagrant-centos65 ~]# mysql -uroot -pxxxx(重新登录)<br> <br> mysql> SELECT @@tx_isolation;<br> ---------------- <br> | @@tx_isolation |<br> ---------------- <br> | SERIALIZABLE   |<br> ---------------- <br> 1 row in set (0.00 sec)<br> <br> mysql> select * from test.user;<br> ---- ------ <br> | id | name |<br> ---- ------ <br> |  2 | b    |<br> |  4 | d    |<br> ---- ------ <br> 2 rows in set (0.00 sec)<br> <br> mysql> begin;<br> Query OK, 0 rows affected (0.00 sec)<br> <br> mysql> insert into test.user values (5, 'e');<br> Query OK, 1 row affected (0.00 sec)<br> <br> [窗口B]:<br> <br> mysql> quit;<br> Bye<br> <br> [root@vagrant-centos65 ~]# mysql -uroot -pxxxx(重新登录)<br> <br> mysql> SELECT @@tx_isolation;<br> ---------------- <br> | @@tx_isolation |<br> ---------------- <br> | SERIALIZABLE   |<br> ---------------- <br> 1 row in set (0.00 sec)<br> <br> mysql> select * from test.user;<br> ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction<br> <br> [窗口A]:<br> <br> mysql> commit;<br> Query OK, 0 rows affected (0.01 sec)<br> <br> [窗口B]:<br> <br> mysql> mysql> select * from test.user;<br> ---- ------ <br> | id | name |<br> ---- ------ <br> |  2 | b    |<br> |  4 | d    |<br> |  5 | e    |<br> ---- ------ <br> 3 rows in set (0.00 sec)Danke ~

Quelle: http://mp.weixin.qq.com/s?__biz=MjM5NDM4MDIwNw==&mid=2448834642&idx=1&sn=c02c5cc8ab0c1f29142ac8f8aa6b78af#rd

Für mehr [trockenen Informationsaustausch] folgen Sie bitte meinem persönlichen Abonnementkonto.
Vier Isolationsstufen von MySQL-Transaktionen

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn