• 数据库事务


    1、数据库事务基本特征

        1.原子性

        2.一致性

        3.隔离性

        4.持久性

    2、第一类丢失更新

    假设要更新一个计数器count=10,事务1将count+1(即update count=11),事务2也将count+1,当事务1提交 成功,事务2提交成功,事务2失败回滚,回滚到最初态count=10,事务1的更新将被丢失

     3、第二类丢失更新

    假设要更新一个计数器count(10),事务1将count+1,事务2也将count+1,那么两个事务提交后,count更新为11和意想的12不一致

    注意:设置隔离等级并不能解决第二类更新丢失,隔离等级决定的是事务查询更新处于怎么样的环境,无论隔离等级如何,

    第二类更新丢失总是存在,因为它是以后者覆盖前者,和隔离时的可见性没有必然联系。MySQL的update是互斥的,即一个在update(可能是事务),另一update必须阻塞直到其他update完成(事务提交),这样一来,无论隔离等级如何,使用count=count+1这种方式更新是不会出现第二类更新

    二、隔离等级

    1、查询当前隔离等级

    Select @@tx_isolation/@@transaction_isolation;

    2、设置当前会话隔离等级

    Set session transaction isolation level isolation_level(read uncommitted, read committed, repeatable read, serializable;

    3、read uncommitted读未提交

        在一次事务中,若其他事务产生了更新或插入(尽管未提交),该事务查询可见更新或插入

        1、在进行数据库操作的两个事务,事务1( READ-COMMITTED)进行update操作,事务2(READ-UNCOMMITTED)进行查询操作(事务1提交前),事务2能成功查询到事务1的未提交更新

    事务1:

     1 mysql> select @@tx_isolation;
     2 
     3 +---------------------------+
     4 
     5 |    @@tx_isolation    |
     6 
     7 +---------------------------+
     8 
     9 | READ-COMMITTED |
    10 
    11 +---------------------------+
    12 
    13 1 row in set (0.00 sec)
    14 
    15  
    16 
    17 mysql> begin;
    18 
    19 Query OK, 0 rows affected (0.00 sec)
    20 
    21 mysql> select * from user;
    22 
    23 +----+-----------+-----+
    24 
    25 | id | user_name | sex |
    26 
    27 +----+-----------+-----+
    28 
    29 |  1 | jyin      |   1 |
    30 
    31 |  2 | mike      |   1 |
    32 
    33 |  3 | john      |   1 |
    34 
    35 +----+-----------+-----+
    36 
    37 3 rows in set (0.00 sec)
    38 
    39 mysql> update user set sex=2 where id=3;
    40 
    41 Query OK, 1 row affected (0.01 sec)
    View Code

    事务2:

     1 mysql> select @@tx_isolation;
     2 
     3 +------------------+
     4 
     5 | @@tx_isolation   |
     6 
     7 +------------------+
     8 
     9 | READ-UNCOMMITTED |
    10 
    11 +------------------+
    12 
    13 1 row in set (0.00 sec)
    14 
    15  
    16 
    17 mysql> begin;
    18 
    19 Query OK, 0 rows affected (0.00 sec)
    20 
    21 mysql> select * from user;
    22 
    23 +----+-----------+-----+
    24 
    25 | id | user_name | sex |
    26 
    27 +----+-----------+-----+
    28 
    29 |  1 | jyin      |   1 |
    30 
    31 |  2 | mike      |   1 |
    32 
    33 |  3 | john      |   2 |
    34 
    35 +----+-----------+-----+
    View Code

        2、反之,事务1无法查询到事务2的未提交更新

    事务1(事务2进行update操作后)

     1 mysql> begin;
     2 
     3 Query OK, 0 rows affected (0.00 sec)
     4 
     5 mysql> select * from user;
     6 
     7 +----+-----------+-----+
     8 
     9 | id | user_name | sex |
    10 
    11 +----+-----------+-----+
    12 
    13 |  1 | jyin      |   1 |
    14 
    15 |  2 | mike      |   1 |
    16 
    17 |  3 | john      |   1 |
    18 
    19 +----+-----------+-----+
    20 
    21 3 rows in set (0.00 sec)
    View Code 

    事务2

    1 mysql> begin;
    2 
    3 Query OK, 0 rows affected (0.00 sec)
    4 
    5 mysql> update user set sex=2;
    6 
    7 Query OK, 3 rows affected (0.02 sec)
    8 
    9 Rows matched: 3  Changed: 3  Warnings: 0
    View Code 

    4、read committed读已提交

        在一次事务中,若其他事务产生了更新插入提交,该事务查询可见提交

    5、repeatable read可重读

        在一次事务中,第一次查询和第二次查询结果一致(中间无主动更新或插入),对其他事务更新插入提交不可见

    事务1

     1 mysql> begin;
     2 
     3 Query OK, 0 rows affected (0.00 sec)
     4 
     5 mysql> select * from user;
     6 
     7 +----+-----------+-----+
     8 
     9 | id | user_name | sex |
    10 
    11 +----+-----------+-----+
    12 
    13 |  1 | jyin      |   1 |
    14 
    15 |  2 | mike      |   1 |
    16 
    17 |  3 | john      |   2 |
    18 
    19 +----+-----------+-----+
    20 
    21 3 rows in set (0.01 sec)
    22 
    23  
    24 
    25 mysql> update user set sex=1 where id=3;
    26 
    27 Query OK, 1 row affected (0.01 sec)
    28 
    29 Rows matched: 1  Changed: 1  Warnings: 0
    View Code 

    在事务1提交前进行事务2(repeatable read)

     1 mysql> begin;
     2 
     3 Query OK, 0 rows affected (0.00 sec)
     4 
     5 mysql> select * from user;
     6 
     7 +----+-----------+-----+
     8 
     9 | id | user_name | sex |
    10 
    11 +----+-----------+-----+
    12 
    13 |  1 | jyin      |   1 |
    14 
    15 |  2 | mike      |   1 |
    16 
    17 |  3 | john      |   2 |
    18 
    19 +----+-----------+-----+
    20 
    21 3 rows in set (0.00 sec)
    View Code

    然后事务1提交,事务2再次进行查询

     1 mysql> select * from user;
     2 
     3 +----+-----------+-----+
     4 
     5 | id | user_name | sex |
     6 
     7 +----+-----------+-----+
     8 
     9 |  1 | jyin      |   1 |
    10 
    11 |  2 | mike      |   1 |
    12 
    13 |  3 | john      |   2 |
    14 
    15 +----+-----------+-----+
    16 
    17 3 rows in set (0.00 sec)
    18 
    19  
    20 
    21 mysql> commit;
    22 
    23 Query OK, 0 rows affected (0.00 sec)
    24 
    25  
    26 
    27 mysql> select * from user;
    28 
    29 +----+-----------+-----+
    30 
    31 | id | user_name | sex |
    32 
    33 +----+-----------+-----+
    34 
    35 |  1 | jyin      |   1 |
    36 
    37 |  2 | mike      |   1 |
    38 
    39 |  3 | john      |   1 |
    40 
    41 +----+-----------+-----+
    42 
    43 3 rows in set (0.00 sec)
    View Code

    6、serializable

        在一次事务中,在进行更新或插入操作时,其他事务开始更新或插入,该事务将被阻塞,直到其他事务被提交

    事务1

    1 mysql> begin;
    2 
    3 Query OK, 0 rows affected (0.00 sec)
    4 
    5 mysql> insert user(user_name, sex) values('cherry', 2);
    6 
    7 Query OK, 1 row affected (0.01 sec)
    View Code 

    在提交前进行事务2

     1 mysql> select @@tx_isolation;
     2 
     3 +----------------+
     4 
     5 | @@tx_isolation |
     6 
     7 +----------------+
     8 
     9 | SERIALIZABLE   |
    10 
    11 +----------------+
    12 
    13 1 row in set (0.00 sec)
    14 
    15  
    16 
    17 mysql> begin;
    18 
    19 Query OK, 0 rows affected (0.00 sec)
    20 
    21 mysql> select * from user;(在此阻塞直到事务1提交才能完成查询)
    22 
    23 +----+-----------+-----+
    24 
    25 | id | user_name | sex |
    26 
    27 +----+-----------+-----+
    28 
    29 |  1 | jyin      |   1 |
    30 
    31 |  2 | mike      |   1 |
    32 
    33 |  3 | john      |   1 |
    34 
    35 |  4 | cherry    |   2 |
    36 
    37 +----+-----------+-----+
    38 
    39 4 rows in set (11.78 sec)
    View Code

    如果事务2在事务1进行插入或更新操作前进行查询,然后事务1进行插入或更新,事务1会被阻塞直到事务2提交

    6、隔离等级和可能发生的现象

     

    脏读

    不可重复读

    幻读

    未提交读

    读写提交

    ×

    可重复读

    ×

    ×

    串行化

    ×

    ×

    ×

  • 相关阅读:
    小程序首页不显示tabbar
    小程序之背景音乐——wx.backgroundAudioManager
    根据浏览器分辨率自动调整网页宽度的一个例子
    vue 限制input[type=number]的输入位数策略整理
    php刷新当前页面
    PHP中获取当前页面的完整URL
    如何使用php session
    常用网页播放器代码
    php session 生命周期代码实例
    去掉删除discuz x3.2 的-Powered by Discuz!
  • 原文地址:https://www.cnblogs.com/Atua/p/11459823.html
Copyright © 2020-2023  润新知