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

发表于:2022-7-12 09:14

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:吃果冻不吐果冻皮    来源:掘金

#
MySQL
  数据库的多版本并发控制(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。
  查看当前会话隔离级别
  方式一:
mysql> show variables like 'transaction_isolation';
+-----------------------+--------------+
| Variable_name  | Value |
+-----------------------+--------------+
| transaction_isolation | SERIALIZABLE |
+-----------------------+--------------+
  方式二:
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| SERIALIZABLE            |
+-------------------------+
  MySQL 中的事务操作
  事务分为隐式事务和显式事务。
  MySQL 中事务默认是隐式事务,执行insert、update、delete操作的时候,数据库自动开启事务、提交或回滚事务。是否开启隐式事务是由变量autocommit控制的。
  隐式事务
  事务自动开启、提交或回滚,比如insert、update、delete语句,事务的开启、提交或回滚由mysql内部自动控制的。
  查看变量autocommit是否开启了自动提交,autocommit为ON表示开启了自动提交。
mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit   | ON   |
+---------------+-------+
  显式事务
  事务需要手动开启、提交或回滚,由开发者自己控制。有 2 种方式手动控制事务。
  用 START来开始一个事务
  语法:
// 开启事务
start transaction;
// 执行事务操作(事务回滚/事务确认)
commit|rollback;
  示例:提交事务操作。
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test1 values (2);
Query OK, 1 row affected (0.00 sec)
mysql> insert into test1 values (3);
Query OK, 1 row affected (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
  用 SET 来改变 MySQL 的自动提交模式
  SET AUTOCOMMIT=0 禁止自动提交
  SET AUTOCOMMIT=1 开启自动提交
  语法:
// 设置不自动提交事务set autocommit=0;
// 执行事务操作commit|rollback;
  示例:回滚事务操作。
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test1 values(2);
Query OK, 1 row affected (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
  总结
  为了达到事务的四大特性,数据库定义了4种不同的事务隔离级别,由低到高依次为读未提交、读已提交、可重复读以及可串行化,这四个级别可以逐个解决脏读、不可重复读、幻读这几类问题。隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。
  事务隔离级别为读已提交时,写数据只会锁住相应的行。
  事务隔离级别为串行化时,读写数据都会锁住整张表。
  InnoDB 存储引擎默认使用可重复读隔离级别。在分布式事务的情况下,InnoDB 存储引擎一般会用到可串行化隔离级别。
  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号