51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

查看: 471|回复: 0

MySQL数据库事务内容详解(二)

[复制链接]
  • TA的每日心情
    无聊
    前天 09:12
  • 签到天数: 918 天

    连续签到: 3 天

    [LV.10]测试总司令

    发表于 2022-7-12 09:30:58 | 显示全部楼层 |阅读模式
     数据库的多版本并发控制(MVCC)原理
      Mysql 默认采用的可重复读隔离级别。每条记录在更新的时候都会同时记录一条回滚操作(回滚操作日志undo log)。同一条记录在系统中可以存在多个版本,这就是数据库的多版本并发控制(MVCC)。即通过回滚(rollback操作),可以回到前一个状态的值。
      假设一个值从 1 被按顺序改成了 2、3、4,在回滚日志里面就会有类似下面的记录。
      当前值是 4,但是在查询这条记录的时候,不同时刻启动的事务会有不同的 read-view。如下图所示,在视图 A、B、C 里面,这一个记录的值分别是 1、2、4,同一条记录在系统中可以存在多个版本,就是数据库的多版本并发控制(MVCC)。
      对于 read-view A,要得到 1,就必须将当前值依次执行图中所有的回滚操作得到。
      同时你会发现,即使现在有另外一个事务正在将 4 改成 5,这个事务跟 read-view A、B、C 对应的事务是不会冲突的。

    提问:回滚操作日志(undo log)什么时候删除?
      MySQL会判断当没有事务需要用到这些回滚日志的时候,回滚日志会被删除。
      提问:那什么时候不需要了?
      当系统里没有比这个回滚日志更早的read-view的时候。
      设置隔离级别
      通过set命令
    SET [GLOBAL|SESSION] TRANSACTION ISOLATION LEVEL level;

    其中,level有4种值:REPEATABLE READ | READ COMMITTED| READ UNCOMMITTED | SERIALIZABLE 。
      关键词:GLOBAL,只对执行完该语句之后产生的会话起作用,当前已经存在的会话无效。
      关键词:SESSION,对当前会话的所有后续的事务有效,该语句可以在已经开启的事务中间执行,但不会影响当前正在执行的事务,如果在事务之间执行,则对后续的事务有效。
      无关键词:只对当前会话中下一个即将开启的事务有效,下一个事务执行完后,后续事务将恢复到之前的隔离级别,该语句不能在已经开启的事务中间执行,会报错的。
      通过服务启动项命令
      可以修改启动参数transaction-isolation的值。比方说,我们在启动服务器时指定了--transaction-isolation=READ UNCOMMITTED,那么事务的默认隔离级别就从原来的REPEATABLE READ变成了READ UNCOMMITTED。
      查看当前会话隔离级别
      方式一:
    1. mysql> show variables like 'transaction_isolation';
    2. +-----------------------+--------------+
    3. | Variable_name  | Value |
    4. +-----------------------+--------------+
    5. | transaction_isolation | SERIALIZABLE |
    6. +-----------------------+--------------+
    复制代码
    方式二:
    1. +-------------------------+
    2. | @@transaction_isolation |
    3. +-------------------------+
    4. | SERIALIZABLE            |
    5. +-------------------------+
    复制代码
    MySQL 中的事务操作
      事务分为隐式事务和显式事务。
      MySQL 中事务默认是隐式事务,执行insert、update、delete操作的时候,数据库自动开启事务、提交或回滚事务。是否开启隐式事务是由变量autocommit控制的。
      隐式事务
      事务自动开启、提交或回滚,比如insert、update、delete语句,事务的开启、提交或回滚由mysql内部自动控制的。
      查看变量autocommit是否开启了自动提交,autocommit为ON表示开启了自动提交。
    1. mysql> show variables like 'autocommit';
    2. +---------------+-------+
    3. | Variable_name | Value |
    4. +---------------+-------+
    5. | autocommit   | ON   |
    6. +---------------+-------+
    复制代码
    显式事务
      事务需要手动开启、提交或回滚,由开发者自己控制。有 2 种方式手动控制事务。
      用 START来开始一个事务
      语法:
    1. // 开启事务
    2. start transaction;
    3. // 执行事务操作(事务回滚/事务确认)
    4. commit|rollback;
    复制代码
    示例:提交事务操作。
    1. mysql> start transaction;
    2. Query OK, 0 rows affected (0.00 sec)
    3. mysql> insert into test1 values (2);
    4. Query OK, 1 row affected (0.00 sec)
    5. mysql> insert into test1 values (3);
    6. Query OK, 1 row affected (0.00 sec)
    7. mysql> commit;
    8. Query OK, 0 rows affected (0.00 sec)
    复制代码
    用 SET 来改变 MySQL 的自动提交模式
      SET AUTOCOMMIT=0 禁止自动提交
      SET AUTOCOMMIT=1 开启自动提交
      语法:
    1. // 设置不自动提交事务set autocommit=0;
    2. // 执行事务操作commit|rollback;
    复制代码
    示例:回滚事务操作。
    1. mysql> set autocommit=0;
    2. Query OK, 0 rows affected (0.00 sec)
    3. mysql> insert into test1 values(2);
    4. Query OK, 1 row affected (0.00 sec)
    5. mysql> rollback;
    6. Query OK, 0 rows affected (0.00 sec)
    复制代码
    总结
      为了达到事务的四大特性,数据库定义了4种不同的事务隔离级别,由低到高依次为读未提交、读已提交、可重复读以及可串行化,这四个级别可以逐个解决脏读、不可重复读、幻读这几类问题。隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。
      事务隔离级别为读已提交时,写数据只会锁住相应的行。
      事务隔离级别为串行化时,读写数据都会锁住整张表。
      InnoDB 存储引擎默认使用可重复读隔离级别。在分布式事务的情况下,InnoDB 存储引擎一般会用到可串行化隔离级别。







    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?(注-册)加入51Testing

    x
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-3-29 04:56 , Processed in 0.062412 second(s), 25 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表