查看默认的隔离级别:
select @@tx_isolation
注:默认的隔离级别是可重复读。
读未提交
窗口一设置隔离级别为读未提交
set session transaction isolation level read uncommitted;
start transaction;
insert into luna values(1,'dd','1',now());
窗口二查看数据
select * from luna
注:窗口2并未有数据产生,因为默认的情况下,是可重复读。
MariaDB [gap]> set session transaction isolation level read uncommitted;
Query OK, 0 rows affected (0.00 sec)
MariaDB [gap]> select * from luna;
+------+------+------+------------+
| id | name | sex | logtime |
+------+------+------+------------+
| 1 | dd | 1 | 2018-10-15 |
+------+------+------+------------+
1 row in set (0.00 sec)
注:设置未提交读,就会有数据产生,这样就出现脏读。一般不太会被使用。
读已提交
窗口一设置隔离级别为读已提交
set session transaction isolation level read committed;
start transaction;
insert into luna values(1,'dd','1',now());
窗口二查看数据
MariaDB [gap]> set session transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)
MariaDB [gap]> start transaction;
Query OK, 0 rows affected (0.00 sec)
注:此种情况,只有被提交了
读未提交
窗口一设置隔离级别为读未提交
set session transaction isolation level read uncommitted;
start transaction;
insert into luna values(1,'dd','1',now());
窗口二查看数据
select * from luna
注:窗口2并未有数据产生,因为默认的情况下,是可重复读。
MariaDB [gap]> set session transaction isolation level read uncommitted;
Query OK, 0 rows affected (0.00 sec)
MariaDB [gap]> select * from luna;
+------+------+------+------------+
| id | name | sex | logtime |
+------+------+------+------------+
| 1 | dd | 1 | 2018-10-15 |
+------+------+------+------------+
1 row in set (0.00 sec)
注:设置未提交读,就会有数据产生,这样就出现脏读。一般不太会被使用
解决脏读。
可重复读
窗口一设置隔离级别为可重复读
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from gap;
+------+
| id |
+------+
| 22 |
| 33 |
| 39 |
| 42 |
| 43 |
| 100 |
+------+
6 rows in set (0.00 sec)
mysql> update gap set id=23 where id=22;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> commit;
窗口二查看数据
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from gap;
+------+
| id |
+------+
| 22 |
| 33 |
| 39 |
| 42 |
| 43 |
| 100 |
+------+
6 rows in set (0.00 sec)
mysql> select * from gap;
+------+
| id |
+------+
| 22 |
| 33 |
| 39 |
| 42 |
| 43 |
| 100 |
+------+
6 rows in set (0.00 sec)
注: 解决重复读的问题。
串行化
窗口一设置隔离级别为中行化
set session transaction isolation level serializable;
start transaction;
select * from luna;
窗口二查看数据
注:此时数据插入不进去。
其他的一些概念
- 脏读:事务A修改了一个数据,但未提交,事务B读到了事务A未提交的更新结果,如果事务A提交失败,事务B读到的就是脏数据。
- 不可重复读:在同一个事务中,对于同一份数据读取到的结果不一致。比如,事务B在事务A提交前读到的结果,和提交后读到的结果可能不同。
- 幻读:在同一个事务中,同一个查询多次返回的结果不一致。事务A新增了一条记录,事务B在事务A提交前后各执行了一次查询操作,发现后一次比前一次多了一条记录。
另一种概念:
脏读:指一个线程中的事务读取到了另外一个线程中未提交的数据。
不可重复读:指一个线程中的事务读取到了另外一个线程中提交的update的数据。
虚读:指一个线程中的事务读取到了另外一个线程中提交的insert的数据。
补充说明
--全新的补充:
1、事务隔离级别为读提交时,写数据只会锁住相应的行
2、事务隔离级别为可重复读时,如果检索条件有索引(包括主键索引)的时候,默认加锁方式是next-key 锁;如果检索条件没有索引,更新数据时会锁住整张表。一个间隙被事务加了锁,其他事务是不能在这个间隙插入记录的,这样可以防止幻读。
3、事务隔离级别为串行化时,读写数据都会锁住整张表
4、隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。
5、MYSQL MVCC实现机制参考链接:https://blog.csdn.net/whoamiyang/article/details/51901888
6、关于next-key 锁可以参考链接:https://blog.csdn.net/bigtree_3721/article/details/73731377