Mysql事务隔离级别_MySQL

WBOY
WBOYオリジナル
2016-06-01 13:00:061525ブラウズ

<code class=" hljs brainfuck">scott@PROD>select * from dept1;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        50 OPERATIONS     BOSTON
        20 DBA            Bei Jing
<code class=" hljs vbnet">scott@PROD>update dept1 set deptno=21 where dname='DBA';

1 row updated.

scott@PROD>SELECT s.sid, s.serial#,
  2     CASE BITAND(t.flag, POWER(2, 28))
  3        WHEN 0 THEN 'READ COMMITTED'
  4        ELSE 'SERIALIZABLE'
  5     END AS isolation_level
  6  FROM v$transaction t 
  7  JOIN v$session s ON t.addr = s.taddr
  8  AND s.sid = sys_context('USERENV', 'SID');

       SID    SERIAL# ISOLATION_LEVE
---------- ---------- --------------
        41       5973 READ COMMITTED

Oracle数据库支持READ COMMITTED 和 SERIALIZABLE这两种事务隔离级别。
而Mysql支持READ UNCOMMITED,READ COMMITED,REPEATABLE READ,SERIALIZABLE四种事务隔离级别

READ UNCOMMITTED(读取未提交内容)
在read uncommitted隔离级别,所有事物都可以”看到”未提交事物的执行结果。也就是脏读(读取未提交事务)

READ COMMITED (读取提交内容)
ORACLE的默认隔离级别。一个事物开始时,只能”看见”已经提交事务所做的改变,一个事务从开始提交前,所做的任何数据改变都是不可见的,除非已经提交。这种隔离级别也就是不可重复读

REPEATABLE READ (可重读)
repeatable read隔离级别解决了read uncommitted隔离级导致的问题。它确保同一事务的做个实例在并发读取数据时,会”看到”同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读。简单来说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了薪行,当用户再读取该范围的数据行时,会发现有新的”还原”行。

SERIALIZABLE (可串行化)
serializable是最高级别的隔离级,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。

Mysql默认的隔离级别是:

<code class=" hljs asciidoc">(mysql@localhost) [fandb]> select @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+
<code class=" hljs asciidoc">session A:
(mysql@localhost) [fandb]> begin;
Query OK, 0 rows affected (0.00 sec)

(mysql@localhost) [fandb]> update per1 set name='fan1' where id=1
    -> ;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

(mysql@localhost) [fandb]> select * from per1 limit 1;
+----+------+
| id | name |
+----+------+
|  1 | fan1 |
+----+------+
1 row in set (0.00 sec)
A会话更新一行
<code class=" hljs asciidoc">session B:
(mysql@localhost) [fandb]> begin;
Query OK, 0 rows affected (0.00 sec)

(mysql@localhost) [fandb]> select * from per1 limit 1;
+----+------+
| id | name |
+----+------+
|  1 | fan  |
+----+------+
1 row in set (0.00 sec)
此时在B开始事务并查询,id=1的name列并没有变化
<code class=" hljs css">session A:
(mysql@localhost) [fandb]> commit;
Query OK, 0 rows affected (0.00 sec)
接着A会话提交
<code class=" hljs asciidoc">session B:
(mysql@localhost) [fandb]> select * from per1 limit 1;
+----+------+
| id | name |
+----+------+
|  1 | fan  |
+----+------+
1 row in set (0.00 sec)
在去B会话查询,还是没有变化
<code class=" hljs asciidoc">(mysql@localhost) [fandb]> commit;
Query OK, 0 rows affected (0.00 sec)

(mysql@localhost) [fandb]> select * from per1 limit 1;
+----+------+
| id | name |
+----+------+
|  1 | fan1 |
+----+------+
1 row in set (0.00 sec)
只有当B会话事务结束,再次查询记录才会变化
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。