什么是事务隔离级别,事务隔离级别详解

                                   生命中曾经有过的所有灿烂,原来终究,都需要用寂寞来偿还。

                                   

 

    在IT行业,无论是oracle,mysql,还是postgresql数据库,为了保证数据库并发性能和数据一致性,都实现了MVCC功能(多版本并发控制)。用户通过会话访问数据库,内部数据库通过事务来完成用户提交的一项一项请求。

 

 

    事务中,为了达到AIID属性,数据库中都实现了相应的隔离级别。在SQL标准中,定义了四种隔离级别。

 

1,read uncommitted(未提交读)

     在未提交读级别,事务中的修改,即使没有提交,对其他的事务也都是可以看见的。事务可以读取未提交的数据,

     这也被称为脏读(Dirty Read)。这个级别会导致很多问题,所有一般很少使用。

 

2,read commited(提交读)

     大多数数据库系统的默认隔离级别都是read commited。read commited满足前面提到的隔离性的简单定义:一个事务

     开始时,只能"看见"已经提交的事务所作的修改。换句话说,一个事务从开始直到提交之前,所做的任何修改对其他

     事务都是不可见的。这个级别有时候也可叫做不可重复读(nonrepeatable read),因为两次执行同样的查询,可能会得到不一样的结果。

 

3,repeatable read(可重复读)

     repeatable read解决了脏读问题。该级别保证了在同一个事务中多次读取同样记录的结果是一致的。但是理论上,可

     重复读级别还是无法解决另外一个幻读(phantom read)的问题。所谓幻读,指的是当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录。当之前的事务再次读取该范围的记录时,会产生幻行(phantom row)。

 

4,serializable(可串行化)

     serializable是最高的隔离级别。它通过强制事务串行执行,避免了前面说的幻读问题。简单来说,serializable会在读取的每一行数据上都加锁。该级别实际中很少使用。

 

                                                                           下面使用mysql来实践:

 

    mysql默认的隔离级别为REPEATABLE-READ。


mysql> show variables like '%tx%';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| tx_isolation  | REPEATABLE-READ |
| tx_read_only  | OFF             |
+---------------+-----------------+
2 rows in set, 1 warning (0.00 sec)

 

1,修改隔离级别为read uncommitted


mysql> set session transaction isolation level read uncommitted;
Query OK, 0 rows affected (0.01 sec)
mysql> show variables like '%tx%';
+---------------+------------------+
| Variable_name | Value            |
+---------------+------------------+
| tx_isolation  | READ-UNCOMMITTED |
| tx_read_only  | OFF              |
+---------------+------------------+
2 rows in set, 1 warning (0.00 sec)

 

    A开启事务,修改数据:

 

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

mysql> update poor_user set password='123456';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

 

    B事务查看数据

 
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from poor_user;
+--------------------------------------+------------------+----------+------------+-----------------------------------------------+
| UserID                               | UserName         | Password | UserBirth  | Descript                                      |
+--------------------------------------+------------------+----------+------------+-----------------------------------------------+
| bbe7faab-7c48-11e9-b4ae-80ce6248ca07 | 唐鹏程,tpc123    | 123456   | 1989-05-13 | 最帅气,最善良,最可爱的男人。|
+--------------------------------------+------------------+----------+------------+-----------------------------------------------+
1 row in set (0.00 sec)

    

    可以看到,数据没有提交,但是我们可以看到未提交的数据,这就是所谓的脏读,所以在数据库中,该模式是不建议使用的。

 

2,修改数据库隔离级别为read committed;

 

mysql> set global transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)

 

    A事务修改数据

 

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

mysql> update poor_user set password='123456';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

 

    开启B事务查看数据

 

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from poor_user;
+--------------------------------------+------------------+----------+------------+-----------------------------------------------+
| UserID                               | UserName         | Password | UserBirth  | Descript                                      |
+--------------------------------------+------------------+----------+------------+-----------------------------------------------+
| bbe7faab-7c48-11e9-b4ae-80ce6248ca07 | 唐鹏程,tpc123    | 123     | 1989-05-13 | 最帅气,最善良,最可爱的男人。|
+--------------------------------------+------------------+----------+------------+-----------------------------------------------+
1 row in set (0.00 sec)

 

    A事务提交数据,B事务查看数据

 

mysql> select * from poor_user;
+--------------------------------------+------------------+----------+------------+-----------------------------------------------+
| UserID                               | UserName         | Password | UserBirth  | Descript                                      |
+--------------------------------------+------------------+----------+------------+-----------------------------------------------+
| bbe7faab-7c48-11e9-b4ae-80ce6248ca07 | 唐鹏程,tpc123    | 123456      | 1989-05-13 | 最帅气,最善良,最可爱的男人。|
+--------------------------------------+------------------+----------+------------+-----------------------------------------------+
1 row in set (0.00 sec)

 

    可以看到,B会话中已经看到A提交的数据了。

 

3,修改数据库隔离级别为repeatable read;

 
mysql> set global transaction isolation level repeatable read;
Query OK, 0 rows affected (0.00 sec
mysql> set session transaction isolation level repeatable read;
Query OK, 0 rows affected (0.00 sec)

 

    A会话开启事务,并修改数据

 

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

mysql> update poor_user set password='888888';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

 

    开启B会话,查看数据


mysql> start transaction;Query OK, 0 rows affected (0.00 sec)
mysql> select * from poor_user;
+--------------------------------------+------------------+----------+------------+-----------------------------------------------+
| UserID                               | UserName         | Password | UserBirth  | Descript                                      |
+--------------------------------------+------------------+----------+------------+-----------------------------------------------+
| bbe7faab-7c48-11e9-b4ae-80ce6248ca07 | 唐鹏程,tpc123    | 123456   | 1989-05-13 | 最帅气,最善良,最可爱的男人。|
+--------------------------------------+------------------+----------+------------+-----------------------------------------------+
1 row in set (0.00 sec)

 

 

    B会话中看到数据没变,A中进行数据提交,B中查看:

 

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

mysql> select * from poor_user;
+--------------------------------------+------------------+----------+------------+-----------------------------------------------+
| UserID                               | UserName         | Password | UserBirth  | Descript                                      |
+--------------------------------------+------------------+----------+------------+-----------------------------------------------+
| bbe7faab-7c48-11e9-b4ae-80ce6248ca07 | 唐鹏程,tpc123    | 123456   | 1989-05-13 | 最帅气,最善良,最可爱的男人。|
+--------------------------------------+------------------+----------+------------+-----------------------------------------------+
1 row in set (0.00 sec)

 

    可以看到,B事务中还是没看到A中提交的数据。此时,B事务进行提交,查看数据:

 

mysql> commit;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from poor_user;
+--------------------------------------+------------------+----------+------------+-----------------------------------------------+
| UserID                               | UserName         | Password | UserBirth  | Descript                                      |
+--------------------------------------+------------------+----------+------------+-----------------------------------------------+
| bbe7faab-7c48-11e9-b4ae-80ce6248ca07 | 唐鹏程,tpc123    | 888888   | 1989-05-13 | 最帅气,最善良,最可爱的男人。|
+--------------------------------------+------------------+----------+------------+-----------------------------------------------+
1 row in set (0.00 sec)

    

    当B事务提交后,他可以看到A事务中提交的数据了。可重复读隔离级别只允许读取已提交记录,而且在一个事务两次读取一个记录期间,其他事务部的更新该记录。

 

    至于可串行化级别,由于在生产环境很少使用,下面只列出它的效果:

    serializable完全锁定字段,若一个事务来查询同一份数据就必须等待,直到前一个事务完成并解除锁定为止。是完整的隔离级别,会锁定对应的数据表格,因而会有效率的问题。

                                                     欢迎大家关注以下公众号进行数据库方面知识探讨:

                                                                              

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值