美文网首页
mysql 事务机制

mysql 事务机制

作者: 技术创造未来 | 来源:发表于2020-12-03 19:43 被阅读0次

一、事务四大特性(ACID)原子性、一致性、隔离性、持久性

原子性(Atomicity):原子性是指,事务包含的所有操作要么成功,要么全部失败回滚。因此事务的操作如果成功,就必须全部应用到数据库,如果操作失败就不能对数据库有影响。

一致性(Consistency):事务必须从一个一致性状态变成换另一个一致性状态,也就是说一个事务执行之前和执行之后必须处于一致性。比如A向B转账¥100,A少了100,B需要多了100,加起来是100才行。

隔离性(Isolation):当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作干扰。

持久性(Durability):

持久性是指,一个事务一旦提交,那么对数据库的改变是永久性的,即使在数据库系统遇到故障的时候 也不会丢失事务的操作。

二、事务隔离级别和实现原理:

 MySQL 事务都是指在 InnoDB 引擎下,MyISAM 引擎是不支持事务的

1、读未提交。(read uncommitted)

2、读提交。(read committed)

3、可重复读(重复读到的值一样)。(repeatable read)在可重复读的事务隔离级别下,读取的是快照数据,总是读取当前事务开始时的行数据版本。

commit 事务以后,再提交才会更新。

4、串行化。(serializable)

隔离级别

注意:MySQL解决了 可重复读的 幻读问题。详见下文

脏读:脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。

不可重复读(重复读到的值会不一样):是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。

使用数据库时候需要使用业务,必须先开启业务:

start transaction;

提交事务:

commit;

取消事务(回滚):

rollback;

mysql> select @@tx_isolation;

+-----------------+

| @@tx_isolation  |

+-----------------+

| REPEATABLE-READ |

+-----------------+

1 row in set, 1 warning (0.00 sec)

MySQL默认隔离级别,repeatable-read(重复读) :

select @@tx_isolation

修改隔离级别的语句是:set [作用域] transaction isolation level [事务隔离级别],

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

把数据库的模式改成读(read uncommitted)未提交:

mysql> set session transaction isolation level read uncommitted;

Query OK, 0 rows affected (0.00 sec)

全局:

set global transaction isolation level read uncommitted;

注意:一定要设置成一样的,事务类型(read uncommitted)。不同终端,不能通用(global, session都不行),必须都得设置才能同步。

读未提交

设置A、B事务级别 查询A、B表

不开启事务,read uncommitted无法实现效果,改变了就改变了,rollback没有效果。

开启事务前,更新操作

开启事务后,操作执行时间线(出现读未提交):【红线代表时间线操作】

操作时间轴 另一个例子

读未提交,其实就是可以读到其他事务未提交的数据,但没有办法保证你读到的数据最终一定是提交后的数据,如果中间发生回滚,那就会出现脏数据问题,读未提交没办法解决脏数据问题。更别提可重复读和幻读了,想都不要想。

读提交

另一个例子

设置read committed/uncommitted时,global不可用,必须用session才可以。

时间线,提交完之后才后被其他线程读取到。

每个 select 语句都有自己的一份快照,而不是一个事务一份,所以在不同的时刻,查询出来的数据可能是不一致的。

读提交解决了脏读的问题,但是无法做到可重复读,也没办法解决幻读。

可重复读

可重复读操作

注意:测试可重复读时,必须开启两个事务。两个线程都要 start transaction;

可重复读:事务A启动后修改了数据,事务B在事务开始和事务A提交之后两个时间节点都读取的数据相同。

可重复读(自己定义):事务A做修改操作,事务B在事务A修改前和修改后,读取到的值一样。注意:事物B读取的事务在commit之后,读取到的就是修改后的值了。

不开启事务时:

不开启事务

开启事务时,插入不成功:

当你在 MySQL 中测试幻读的时候,并不会出现上图的结果,幻读并没有发生,MySQL 的可重复读隔离级别其实解决了幻读问题。

在事务A提交之前,事务B的插入操作只能等待

在事务A提交之前,事务B的插入操作只能等待,这就是间隙锁起得作用。

间隙锁解决幻读等问题

不仅插入 age = 10 的记录需要等待事务A提交,age<10、10<age<30 的记录页无法完成,而大于等于30的记录则不受影响,这足以解决幻读问题了。

这是有索引的情况,如果 age 不是索引列,那么数据库会为整个表加上间隙锁。所以,如果是没有索引的话,不管 age 是否大于等于30,都要等待事务A提交才可以成功插入。

串行化:

串行化是4种事务隔离级别中隔离效果最好的,解决了脏读、可重复读、幻读的问题,但是效果最差,它将事务的执行变为顺序执行,与其他三个隔离级别相比,它就相当于单线程,后一个事务的执行必须等待前一个事务结束。

MySQL 中是如何实现事务隔离的:

首先说读未提交,它是性能最好,也可以说它是最野蛮的方式,因为它压根儿就不加锁,所以根本谈不上什么隔离效果,可以理解为没有隔离。

再来说串行化。读的时候加共享锁,也就是其他事务可以并发读,但是不能写。写的时候加排它锁,其他事务不能并发写也不能并发读。

最后说读提交和可重复读。这两种隔离级别是比较复杂的,既要允许一定的并发,又想要兼顾的解决问题。

解决的原理,锁:

并发写问题的解决方式就是行锁,而解决幻读用的也是锁,叫做间隙锁,MySQL 把行锁和间隙锁合并在一起,解决了并发写和幻读的问题,这个锁叫做 Next-Key锁。

参考文献:https://zhuanlan.zhihu.com/p/117476959

相关文章

  • MySQL优化之事务基础,实战优化的基础知识

    MySQL的逻辑架构 MySQL主键自增机制 MySQL关键词 什么是事务 MySQL 创建事务的基础语法 一组事...

  • 数据库锁及事务整理

    参考文档 MySQL的事务和隔离级别理解事务 - MySQL 事务处理机制《MySQL技术内幕》读书笔记一文说尽M...

  • mysql事务机制

    事务简介 ACID 原子性(Atomicity):事务是数据库的逻辑工作单位,它对数据库的修改要么全部执行,要么全...

  • mysql 事务机制

    一、事务四大特性(ACID)原子性、一致性、隔离性、持久性 原子性(Atomicity):原子性是指,事务包含的所...

  • 后端-优秀文章

    理解事务 - MySQL 事务处理机制 作者从概念到实践队 MySQL 的食物处理机制讲得特别详细。一个人搞定 A...

  • MySQL相关知识点

    MySQL(5)| 五分钟搞清楚 MVCC 机制MySQL (三) | 五分钟搞清楚MySQL事务隔离级别

  • <高性能Mysql>读书笔记

    1 Mysql架构与历史 事务机制ACID 原子性 (atomicity)对于一个事务来说,要么操作全部完成,要么...

  • InnoDB的MVCC机制

    在讲解InnoDB的MVCC机制之前,我们应该了解MySQL所支持的事务,以及各个事务级别的区别和每一个事务级别所...

  • MySql事务实现的机制:MVCC

    MySql事务实现的机制:MVCC 这一篇将简单说明一下最近学习了Mysql的事务实现的简单理解。 如果存在一张A...

  • 【Mysql】从事务到MVCC

    [TOC] 前言 本文主要介绍Mysql的事务特性以及mysql的MVCC机制,这块也是笔者在之前面试中的高频问题...

网友评论

      本文标题:mysql 事务机制

      本文链接:https://www.haomeiwen.com/subject/szfvwktx.html