码迷,mamicode.com
首页 > 数据库 > 详细

MySQL事务

时间:2018-10-13 10:25:36      阅读:204      评论:0      收藏:0      [点我收藏+]

标签:innodb   就会   另一个   资源   0.00   结果   创建   set   ack   

事务:一组原子性的SQL查询,或者说一个独立工作单元。 事务日志: 在Oracle当中,被分解为redo log、undo log,及所谓重做日志和撤销日志 ACID测试: A:atomicity,原子性;整个事务中的所有操作要么全部成功执行,要么全部失败后回滚; C:conststency,一致性;数据库总是从一个一致性状态转换为另一个一致性状态; I:Isolation,隔离性;一个事务所做出的操作在提交之前,是不能为其它所见; D:durability;持久性;一但事务提交,其所做的修改会永久保存于数据库中; 隔离有多种隔离级别; 隔离级别越高,数据的安全性越高,不过它的并发能力就越低,隔离级别越低、并发性就越好,但是数据安全性差 事务: 启动事务:start transaction 结束事务: 1、comit;提交 2、rollback;回滚 注意;只有事务型存储引擎方能支持此类操作; 建议:显示请求和提交事务,而不要使用“自动提交”功能; autocommit={1|0}
示例:
        关闭autocommit

        MariaDB [hellodb]> set autocommit=0;
        Query OK, 0 rows affected (0.00 sec)

        MariaDB [hellodb]> show variables like ‘%auto%‘;
        +--------------------------------------+-------+
        | Variable_name                      | Value |
        +--------------------------------------+-------+
        | auto_increment_increment     | 1     |
        | auto_increment_offset            | 1     |
        | autocommit                            | OFF |
        +--------------------------------------+-------+

    开始事务
        MariaDB [hellodb]> start transaction;
    删除学生表里面的stuid是18和23的学员
        MariaDB [hellodb]> delete from students where stuid in (18,23);
    执行rollback 回滚
        MariaDB [hellodb]> rollback;

事务支持savepoint

        SAVEPOINT identifier
        ROLLBACK [WORK] TO [SAVEPOINT] identifier
        RELEASE SAVEPOINT identifier
savepoint示例:
        # 开始事务
        MariaDB [hellodb]> start transaction;
        Query OK, 0 rows affected (0.00 sec)

        # 先查看下最初的students表里面的所有内容
        MariaDB [hellodb]> select * from students;
        +-------+---------------+-----+--------+---------+-----------+
        | StuID | Name          | Age | Gender | ClassID | TeacherID |
        +-------+---------------+-----+--------+---------+-----------+
        |     1 | Shi Zhongyu   |  22 | M      |       2 |         3 |
        |     2 | Shi Potian    |  22 | M      |       1 |         7 |
        |     3 | Xie Yanke     |  53 | M      |       2 |        16 |
        |     4 | Ding Dian     |  32 | M      |       4 |         4 |
        |     5 | Yu Yutong     |  26 | M      |       3 |         1 |
        |     6 | Shi Qing      |  46 | M      |       5 |      NULL |
        |     7 | Xi Ren        |  19 | F      |       3 |      NULL |
        |     8 | Lin Daiyu     |  17 | F      |       7 |      NULL |
        |     9 | Ren Yingying  |  20 | F      |       6 |      NULL |
        |    10 | Yue Lingshan  |  19 | F      |       3 |      NULL |
        |    11 | Yuan Chengzhi |  23 | M      |       6 |      NULL |
        |    12 | Wen Qingqing  |  19 | F      |       1 |      NULL |
        |    13 | Tian Boguang  |  33 | M      |       2 |      NULL |
        |    14 | Lu Wushuang   |  17 | F      |       3 |      NULL |
        |    15 | Duan Yu       |  19 | M      |       4 |      NULL |
        |    16 | Xu Zhu        |  21 | M      |       1 |      NULL |
        |    17 | Lin Chong     |  25 | M      |       4 |      NULL |
        |    18 | Hua Rong      |  23 | M      |       7 |      NULL |
        |    19 | Xue Baochai   |  18 | F      |       6 |      NULL |
        |    20 | Diao Chan     |  19 | F      |       7 |      NULL |
        |    21 | Huang Yueying |  22 | F      |       6 |      NULL |
        |    22 | Xiao Qiao     |  20 | F      |       1 |      NULL |
        |    23 | Ma Chao       |  23 | M      |       4 |      NULL |
        |    24 | Xu Xian       |  27 | M      |    NULL |      NULL |
        |    25 | Sun Dasheng   | 100 | M      |    NULL |      NULL |
        +-------+---------------+-----+--------+---------+-----------+
        25 rows in set (0.00 sec)
        # 执行delete语句删除学员编号为18的学员信息
        MariaDB [hellodb]> delete from students where stuid=18;
        Query OK, 1 row affected (0.00 sec)
        # 创建一个事务还原点为sp1
        MariaDB [hellodb]> savepoint sp1;
        Query OK, 0 rows affected (0.00 sec)
        # 插入一条信息
        MariaDB [hellodb]> insert into students (name,age,gender) values(‘Jinjiao King‘,100,‘M‘);
        Query OK, 1 row affected (0.00 sec)
        # 创建一个事务还原点为sp2
        MariaDB [hellodb]> savepoint sp2;
        Query OK, 0 rows affected (0.00 sec)
        # 使用update语句更新13号学员的年龄
        MariaDB [hellodb]> update students set age=43 where stuid=13;
        Query OK, 1 row affected (0.00 sec)
        Rows matched: 1  Changed: 1  Warnings: 0
        # 上述操作做完之后查看下表是否发生变化
        MariaDB [hellodb]> select * from students;
        +-------+---------------+-----+--------+---------+-----------+
        | StuID | Name          | Age | Gender | ClassID | TeacherID |
        +-------+---------------+-----+--------+---------+-----------+
        |     1 | Shi Zhongyu   |  22 | M      |       2 |         3 |
        |     2 | Shi Potian    |  22 | M      |       1 |         7 |
        |     3 | Xie Yanke     |  53 | M      |       2 |        16 |
        |     4 | Ding Dian     |  32 | M      |       4 |         4 |
        |     5 | Yu Yutong     |  26 | M      |       3 |         1 |
        |     6 | Shi Qing      |  46 | M      |       5 |      NULL |
        |     7 | Xi Ren        |  19 | F      |       3 |      NULL |
        |     8 | Lin Daiyu     |  17 | F      |       7 |      NULL |
        |     9 | Ren Yingying  |  20 | F      |       6 |      NULL |
        |    10 | Yue Lingshan  |  19 | F      |       3 |      NULL |
        |    11 | Yuan Chengzhi |  23 | M      |       6 |      NULL |
        |    12 | Wen Qingqing  |  19 | F      |       1 |      NULL |
        |    13 | Tian Boguang  |  43 | M      |       2 |      NULL |
        |    14 | Lu Wushuang   |  17 | F      |       3 |      NULL |
        |    15 | Duan Yu       |  19 | M      |       4 |      NULL |
        |    16 | Xu Zhu        |  21 | M      |       1 |      NULL |
        |    17 | Lin Chong     |  25 | M      |       4 |      NULL |
        |    19 | Xue Baochai   |  18 | F      |       6 |      NULL |
        |    20 | Diao Chan     |  19 | F      |       7 |      NULL |
        |    21 | Huang Yueying |  22 | F      |       6 |      NULL |
        |    22 | Xiao Qiao     |  20 | F      |       1 |      NULL |
        |    23 | Ma Chao       |  23 | M      |       4 |      NULL |
        |    24 | Xu Xian       |  27 | M      |    NULL |      NULL |
        |    25 | Sun Dasheng   | 100 | M      |    NULL |      NULL |
        |    26 | Jinjiao King  | 100 | M      |    NULL |      NULL |
        +-------+---------------+-----+--------+---------+-----------+
        25 rows in set (0.00 sec)
        # 对students操作完之后,假如说其中有数据有问题,然后回到之前创建的sp2上
        MariaDB [hellodb]> rollback to sp2;
        Query OK, 0 rows affected (0.00 sec)

        MariaDB [hellodb]> select * from students;
        +-------+---------------+-----+--------+---------+-----------+
        | StuID | Name          | Age | Gender | ClassID | TeacherID |
        +-------+---------------+-----+--------+---------+-----------+
        |     1 | Shi Zhongyu   |  22 | M      |       2 |         3 |
        |     2 | Shi Potian    |  22 | M      |       1 |         7 |
        |     3 | Xie Yanke     |  53 | M      |       2 |        16 |
        |     4 | Ding Dian     |  32 | M      |       4 |         4 |
        |     5 | Yu Yutong     |  26 | M      |       3 |         1 |
        |     6 | Shi Qing      |  46 | M      |       5 |      NULL |
        |     7 | Xi Ren        |  19 | F      |       3 |      NULL |
        |     8 | Lin Daiyu     |  17 | F      |       7 |      NULL |
        |     9 | Ren Yingying  |  20 | F      |       6 |      NULL |
        |    10 | Yue Lingshan  |  19 | F      |       3 |      NULL |
        |    11 | Yuan Chengzhi |  23 | M      |       6 |      NULL |
        |    12 | Wen Qingqing  |  19 | F      |       1 |      NULL |
        |    13 | Tian Boguang  |  33 | M      |       2 |      NULL |
        |    14 | Lu Wushuang   |  17 | F      |       3 |      NULL |
        |    15 | Duan Yu       |  19 | M      |       4 |      NULL |
        |    16 | Xu Zhu        |  21 | M      |       1 |      NULL |
        |    17 | Lin Chong     |  25 | M      |       4 |      NULL |
        |    19 | Xue Baochai   |  18 | F      |       6 |      NULL |
        |    20 | Diao Chan     |  19 | F      |       7 |      NULL |
        |    21 | Huang Yueying |  22 | F      |       6 |      NULL |
        |    22 | Xiao Qiao     |  20 | F      |       1 |      NULL |
        |    23 | Ma Chao       |  23 | M      |       4 |      NULL |
        |    24 | Xu Xian       |  27 | M      |    NULL |      NULL |
        |    25 | Sun Dasheng   | 100 | M      |    NULL |      NULL |
        |    26 | Jinjiao King  | 100 | M      |    NULL |      NULL |
        +-------+---------------+-----+--------+---------+-----------+
        25 rows in set (0.00 sec)
        # 回滚到之前创建sp1的状态上
        MariaDB [hellodb]> rollback to sp1;
        Query OK, 0 rows affected (0.00 sec)
        # 全部回滚到最初状态
        MariaDB [hellodb]> rollback;
        Query OK, 0 rows affected (0.00 sec)

事务隔离级别

事务隔离级别:
        事务本身是需要隔离的,但隔离做的过于严格,任何一个事务都会阻塞其它访问同一个资源的事务,为了避免事务过多的影响其所谓的并发性,我们对事务关系型标准当中对事务的隔离等级做定义,每一种关系型数据库,都可以设定自己到底支持哪种级别,大多数数据库默认情况下都支持到第二种,但mysql支持第三级别
事务的四种隔离级别:(mysql默认是REPEATABLE READ 可重复读)
        READ UNCOMMITED     (读未提交)
            脏读、不可重复读、幻读
        READ COMMITTED      (读提交)
            不可重复读、幻读
        REPEATABLE READ     (可重读)
            幻读
        SERIALIZABILE       (可串行化)
            加锁读

    可能存在问题:
            脏读:         读别人未提交的数据
            不可重复读:  读别人提交的数据也可以,但是别人提交以后产生一个问题查看的结果是之前看到的数据,看不到后面提交的新数据,不可重复读,两次读到的数据是不一样的
            幻读:             即读取过程中,即使有其它提交的事务修改数据,仍只能读取到未修改前的旧数据。
            加锁读:

            tx_isolation:服务器变量,默认为REPEATABLE-READ;可在session级别进行修改

        MVCC:多版本并发控制
    死锁:
        两个或多个事务在同一资源相互占用,并请求锁定对方占用的资源的状态;
        数据库为了解决这样的问题,设计了各种死锁检测、和死锁超时时长

    事务日志:
        事务日志的写入类型为“追加”、因此其操作为“顺序IO”,此日志通常也被称为“预写式日志(write ahead logging)”;

        innodb_log_file_size                      
        innodb_log_files_in_group                  
        innodb_log_group_home_dir 
事务的隔离级别示例:

脏读实验:
    为了实验效果多开一个会话窗口,并且两边都把autocommit自动提交事务给关闭掉
        MariaDB [hellodb]> set autocommit=0;
        MariaDB [hellodb]> show variables like ‘%auto%‘;
        +------------------------------+-------+
        | Variable_name                | Value |
        +------------------------------+-------+
        | auto_increment_increment     | 1     |
        | auto_increment_offset        | 1     |
        | autocommit                   | OFF   |
        +------------------------------+-------+

    1、把两个会话改为READ-UNCOMMITTED模式;
        MariaDB [hellodb]> show global variables like ‘%isola%‘;
        +---------------+-----------------+
        | Variable_name | Value           |
        +---------------+-----------------+
        | tx_isolation  | REPEATABLE-READ |
        +---------------+-----------------+
        1 row in set (0.00 sec)

        MariaDB [hellodb]> set tx_isolation=‘READ-UNCOMMITTED‘;
        Query OK, 0 rows affected (0.00 sec)

        在两个会话上都启用事务
        MariaDB [hellodb]> start transaction;
        Query OK, 0 rows affected (0.00 sec)

        在第一个会话中修改students表里面的13号学员的年龄为40
        MariaDB [hellodb]> update students set age=40 where stuid=13;
        Query OK, 1 row affected (0.00 sec)
        Rows matched: 1  Changed: 1  Warnings: 0
        MariaDB [hellodb]> select * from students where stuid=13;
        +-------+--------------+-----+--------+---------+-----------+
        | StuID | Name         | Age | Gender | ClassID | TeacherID |
        +-------+--------------+-----+--------+---------+-----------+
        |    13 | Tian Boguang |  40 | M      |       2 |      NULL |
        +-------+--------------+-----+--------+---------+-----------+
        1 row in set (0.00 sec)

        然后在第二个会话里面查看是不是能看到13号学员的修改后的数据库此时第一个窗口并未提交事务
        MariaDB [hellodb]> select * from students where stuid=13;
        +-------+--------------+-----+--------+---------+-----------+
        | StuID | Name         | Age | Gender | ClassID | TeacherID |
        +-------+--------------+-----+--------+---------+-----------+
        |    13 | Tian Boguang |  40 | M      |       2 |      NULL |
        +-------+--------------+-----+--------+---------+-----------+
        1 row in set (0.00 sec)
----------------------------------------------------------------------------------------
REPEATABLE-READ模式:
    设置为REPEATABLE-READ
    MariaDB [hellodb]> set tx_isolation=‘REPEATABLE-READ‘;                   
    Query OK, 0 rows affected (0.00 sec)

    删除stuid为3的学员
    MariaDB [hellodb]> delete from students where stuid=3;
    Query OK, 1 row affected (0.00 sec)
    在第一会话提交事务
    MariaDB [hellodb]> commit;
    Query OK, 0 rows affected (0.00 sec)

    在第一会话查询stuid为3的已经查不到了
    MariaDB [hellodb]> select * from students where stuid=3;
    Empty set (0.00 sec)

    在第二个会话中查询还是可以查询到,这就产生了幻读,这种模式解决了不可重复读,不过还是避免不了幻读的问题
    MariaDB [hellodb]> select * from students where stuid = 3;
    +-------+-----------+-----+--------+---------+-----------+
    | StuID | Name      | Age | Gender | ClassID | TeacherID |
    +-------+-----------+-----+--------+---------+-----------+
    |     3 | Xie Yanke |  53 | M      |       2 |        16 |
    +-------+-----------+-----+--------+---------+-----------+
    1 row in set (0.00 sec)

    只有在第二会话中执行提交事务之后再次查询就没有出现了
    MariaDB [hellodb]> commit;
    Query OK, 0 rows affected (0.00 sec)

    MariaDB [hellodb]> select * from students where stuid=3;
    Empty set (0.00 sec)
----------------------------------------------------------------------------------
SERIALIZABLE 加锁读示例:
    1、设置模式为SERIALIZABLE
        MariaDB [hellodb]> set tx_isolation=‘SERIALIZABLE‘;
        Query OK, 0 rows affected (0.00 sec)

    2、修改stuid为14的年龄
        MariaDB [hellodb]> update students set age=21 where stuid=14;

    3、在本窗口查询修改结果
        MariaDB [hellodb]> select * from students where stuid=14;
        +-------+-------------+-----+--------+---------+-----------+
        | StuID | Name        | Age | Gender | ClassID | TeacherID |
        +-------+-------------+-----+--------+---------+-----------+
        |    14 | Lu Wushuang |  21 | F      |       3 |      NULL |
        +-------+-------------+-----+--------+---------+-----------+

    4、在第二个会话窗口查询,只要执行查询之后就会被阻塞,然后过了一定时长系统会提示超时
        MariaDB [hellodb]> select * from students;
        ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

    5、第一窗口执行提交事务
        MariaDB [hellodb]> commit;
        Query OK, 0 rows affected (0.02 sec)

    6、再在第二窗口查询,就可以查询
        MariaDB [hellodb]> select * from students where stuid=14;
        +-------+-------------+-----+--------+---------+-----------+
        | StuID | Name        | Age | Gender | ClassID | TeacherID |
        +-------+-------------+-----+--------+---------+-----------+
        |    14 | Lu Wushuang |  21 | F      |       3 |      NULL |
        +-------+-------------+-----+--------+---------+-----------+
        1 row in set (0.00 sec)

MySQL事务

标签:innodb   就会   另一个   资源   0.00   结果   创建   set   ack   

原文地址:http://blog.51cto.com/dklwj/2299493

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!