6

深入 MySQL (三) 事务

 3 years ago
source link: https://blog.duval.top/2021/02/04/%E6%B7%B1%E5%85%A5-MySQL-3-%E4%BA%8B%E5%8A%A1/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

从前文,我们了解到有一部分存储引擎是支持事务的。本文我们将探讨事务的重要概念以及实现原理。

ACID概念

ACID(Atomicity、Consistency、Isolation、Durability,即原子性、一致性、隔离性、持久性)

隔离性和隔离级别

SQL标准里定义了四种事务隔离级别:

  • 读未提交:一个事务还没提交时,它做的变更就能被别的事务看到;
  • 读提交:一个事务提交之后,它做的变更才会被其他事务看到;
  • 可重复读:一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。当然在可重复读隔离级别下,未提交变更对其他事务也是不可见的;
  • 串行化:对于同一行记录,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。

四种隔离级别区别:

隔离级别 脏读可能性 不可重复读可能性 幻读可能性 加锁读 读未提交 Y Y Y N 读提交 N Y Y N 可重复读 N N Y N 串行化 N N N Y

MySQL中的事务

MySQL提供了两种事务型存储引擎:InnoDB 和 NDB Cluster,而MyISAM并不支持事务。

MVCC与事务隔离实现

四种隔离级别的在InnoDB实现:

  • 读未提交:直接返回记录上的最新值,没有视图概念;
  • 读提交:在每个SQL语句开始执行的时候创建视图;
  • 可重复读:在事务启动时创建视图,整个事务存在期间都用这个视图;(注意,InnoDB利用MVCC已经在可重复读隔离级别下避免了幻读问题!!注意和上边的表格内容区分清楚!!!)
  • 串行化:隔离级别下直接用加锁的方式来避免并行访问。
  • 这个所谓的视图其实是通过多版本并发控制(MVCC)来实现。(详情见《高性能MySQL》第三版 1.4 多版本并发控制)

事务的启动

事务启动方式:

  • 1.显式启动事务语句, begin 或 start transaction。配套的提交语句是 commit,回滚语句是 rollback。
  • 2.set autocommit=0,这个命令会将这个线程的自动提交关掉(注意,仅影响当前线程。)。这意味着如果你只执行一个 select 语句,这个事务就启动了,而且并不会自动提交。这个事务持续存在直到你主动执行 commit 或 rollback 语句,或者断开连接。一般建议总是使用 set autocommit=1, 然后通过显式语句的方式来启动事务。

长事务会导致数据库空间,并且占用所资源,生产中应该尽量避免长事务。查询长事务方法:

// 查询超过60秒的事务
select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started))>60

查看修改事务隔离级别

MySQL默认的事务隔离级别是可重复读(REPEATABLE READ)。

可以通过sql查看MySQL事务隔离级别:

show variables like "%isolation%";

MySQL提供了SET TRANSACTION语句,该语句可以改变单个会话或全局的事务隔离级别。语法格式如下:

SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}

其中,SESSION 和 GLOBAL 关键字用来指定修改的事务隔离级别的范围:

  • SESSION:表示修改的事务隔离级别将应用于当前 session(当前 cmd 窗口)内的所有事务;
  • GLOBAL:表示修改的事务隔离级别将应用于所有 session(全局)中的所有事务,且当前已经存在的 session (包括当前session)不受影响;
  • 如果省略 SESSION 和 GLOBAL,表示修改的事务隔离级别将应用于当前 session 内的下一个还未开始的事务。

任何用户都能改变会话的事务隔离级别,但是只有拥有 SUPER 权限的用户才能改变全局的事务隔离级别。

-理解MySQL的锁机制和事务原理


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK