MySQL 事务 异常 事务隔离的级别

 

事务

在你操作数据库的同时,有可能其他用户还会不断地对数据进行增删改查操作。为了避免并行进行时出现混乱,就产生了“事务”。事务就是要保证一组数据库操作,要么全部成功要么全部失败,以此来保证不混乱。

事务支持是在引擎层实现的,MySQL支持多系统,不是所有引擎都支持事务。

 

事务的特性(ACID)

  • Atomicity(原子性):原子即不可分割,即事务是进行数据处理的基本单位
  • Consistency(一致性):事务使数据库从一种状态到另一种状态,且数据库的约束性不被破坏
  • Isolation(隔离性):指事务之间保持独立性,不被其他事务影响的特性。分为四个隔离等级
  • Durability(持久性):事务提交后对数据库的修改时“持久的”,持久性是用过日志来实现的(回滚日志+重做日志)。即使发生故障,数据修改依然有效,因为当事务完成,日志就会被更新,我们依然可以恢复到最后一次成功提交事务时的状态。

原子性是基础,一致性是约束,隔离性是手段,持久性是目的。

 

事务操作方式

Mysql默认参数autocommit = 1compelation = 0

autocommit = 1:每条SQL都自动提交

autocommit = 0:不论是否使用START TRANSACTONBEGIN,总要使用commit才能提交。有些客户端框架会默认连接后先执行set autocommit = 0的命令。这就容易造成长连接,从而造成长事务。

尽量不要长事务,详见"可重复读的实现"

compelation = 0:执行commit仅提交事务

compelation = 1:commit时相当于commit and chain,开启链式事务,提交事务后开启一个相同的事务

compelation = 2: commit时相当于commit and release,提交后会自动断开服务器连接

在MySQL默认的设置下

  • 使用START TRANSACTIONBEGIN显式开启一个事务,然后再用COMMIT提交

  • 使用ROLLBACK进行回滚,或者回滚到ROLLBACK TO [SAVEPOINT]。例如,在一个事务中为有唯一约束(包含主键)的字段插入了 多条有相同值的该字段记录。 那么,在mysql默认情况下就会产生错误,再执行ROLLBACK后就会只有未插入前的数据。如下列代码,执行后前后查询结果一致。

    SELECT * FROM t;
    ...
    BEGIN;
    INSERT INTO t id VALUES 1;
    INSERT INTO t id VALUES 1;
    ROLLBACK;
    SELECT * FROM t;

    需要注意的是,插入错误后只有手动ROLLBACK后才会执行后前后查询结果一致,不执行ROLLBACK的结果是后面的查询结果会比前面多一条id为1的记录。

  • 连续的BEGIN这时数据库会隐式地提交第一个BEGIN事务并进入第二个事务

  • ROLLBACK是仅针对当前事务的。比如连续进行了两个BEGIN事务,在第二个事务中进行ROLLBACK,数据库仅能回滚到第一个事务提交后的状态

 

三种异常

  • 脏读:事务并行进行时,事务A读到了事务B中新增但未提交的内容
  • 不可重复读:事务并行进行,事务A对表进行查询时事务B对表某行进行修改,导致事务A发现两次读取时的结果不同。
  • 幻读:事务并行进行,事务A进行查询时事务B对表新增数据,导致事务A两次读取时读到更多的数据。

 

用于解决异常的四个事务隔离级别

隔离得越严实,效率就会越低,我们需要在生产中寻找一个平衡点,按业务决定。

对于隔离级别从低到高分别是

  • 读未提交(READ UNCOMMIT) --- 允许读到未提交的数据 --- 不使用锁,无法避免三种异常

  • 读已提交(READ COMMIT) --- 只能读到已提交的数据 --- 其本身可避免脏读(也是Oracle和SQL

    Server默认的隔离级别) --- 可以编写带锁的SQL语句来避免“不可重复读”和“幻读”

  • 可重复读(REPEATABLE READ) --- 事务在执行期间看到的数据必须前后一致 --- 避免 “脏读”和“不可重复读” (是MySQL默认的隔离级别)

  • 可串行化(SERIALIZABLE)--- 将所有事务串行化,是最高隔离等级,可以避免所有异常,但是牺牲了并发性

隔离级别效用说明例题:

  • 读未提交:V1=2 V2=2 V3=2
  • 读已提交:V1=1 V2=2 V3=2
  • 可重复读:V1=1 V2=1 V3=2 (事务在执行期间看到的数据必须一致)
  • 可串行化:V1=2 V2=2 V3=2 (串行化时B在执行“将1改为2”时会被锁住,直到事务A被提交

查询mysql当前的隔离等级

mysql> show variables like 'transaction_isolation';
+-----------------------+-----------------+
| Variable_name | Value |
+-----------------------+-----------------+
| transaction_isolation | REPEATABLE-READ |
+-----------------------+-----------------+
1 row in set (0.02 sec)

 

“可重复读”的实现

  • 隔离的实现主要有读写锁多版本并发处理(MVCC)两种方式。(因为读写锁降低了事务并发效率,为了让读写之间也不冲突,就发明了MVCC)

  • 事务隔离的实现拓展阅读见此处,有一定了解后再整理自己的版本

  • 下面简单介绍MVCC利用ReadView(快照)实现可重复读

  • MySQL中每条记录在更新的时候都会同时记录一条回滚日志

在将1依次改为2,3,4的过程中,回滚日志有如下记录
ReadView_A:将2改为1
ReadView_B:将3改为2
ReadView_C:将4改为3
而当前:
值为4

这就让同一条记录在系统中可以有多个版本,这就是MVCC,此时如果有"将4改为5"的事务,它并不会影响回滚日志中的A、B、C。

  • 尽量不要使用长事务:长事务意味着有很多旧的ReadView(影响回滚空间,5.5之前甚至有可能回滚空间大于真实数据),这会导致占用大量的存储空间,而且长事务还会占用锁资源,有可能拖垮整个库。

  • 删除回滚日志:默认情况下,系统会自行判断,当没有事务需要用到这些回滚日志时就会被删除。在上述例子中,如果修改为4之后就commit(相当短的事务),即会造成“没有事务需要用到这些回滚日志”,上述回滚日志就会被删除。

    也就是说事务未提交前可以回滚,提交后回滚日志会被删除(5.7实验通过)

 

MySQL 事务 异常 事务隔离的级别的更多相关文章

  1. EF 多线程TransactionScope事务异常"事务EFTransaction类定义:与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。"

    解决方案代码一:使用lock锁定 //对于锁推荐使用静态私有静态变量 private readonly static object _MyLock = new object(); /// <su ...

  2. MySQL进阶15--TCL事务控制语言--建立结束事务/设置断点--默认隔离级别--脏读/幻读/不可重复读

    #TCL事物控制语言 : /* Transaction control language : 事物控制语言 事务: 一个或者一组sql语句组成一个执行单元,这个执行单元要么全部执行,要么全部不执行; ...

  3. 【MySQL】:事务四大特性与隔离级别

    目录 一.事务的概念 二.事务的四大特性 1.原子性 2.一致性 3.隔离性 4.持续性 三.事务语句 1.开启事务:start transaction 2.事务回滚:rollback 指定回滚点 3 ...

  4. 一文彻底读懂MySQL事务的四大隔离级别

    前言 之前分析一个死锁问题,发现自己对数据库隔离级别理解还不够清楚,所以趁着这几天假期,整理一下MySQL事务的四大隔离级别相关知识,希望对大家有帮助~ 事务 什么是事务? 事务,由一个有限的数据库操 ...

  5. Mysql 四种事务隔离级别

    一.前提 时过一年重新拾起博文记录,希望后面都能坚持下来. 接着之前MySql的学习,先记录下这篇. 以下都是基于mysql8 innodb存储引擎进行分析的. 二.事务的ACID特性 A(Atomi ...

  6. 【mysql】关于事务的隔离级别

    一.锁的种类 MySQL中锁的种类很多,有常见的表锁和行锁,也有新加入的Metadata Lock等等,表锁是对一整张表加锁,虽然可分为读锁和写锁,但毕竟是锁住整张表,会导致并发能力下降,一般是做dd ...

  7. mysql中不同事务隔离级别下数据的显示效果--转载

    事务是一组原子性的SQL查询语句,也可以被看做一个工作单元.如果数据库引擎能够成功地对数据库应用所有的查询语句,它就会执行所有查询,如果任何一条查询语句因为崩溃或其他原因而无法执行,那么所有的语句就都 ...

  8. 浅谈mysql中不同事务隔离级别下数据的显示效果

    事务的概念 事 务是一组原子性的SQL查询语句,也可以被看做一个工作单元.如果数据库引擎能够成功地对数据库应用所有的查询语句,它就会执行所有查询,如果任何一条查 询语句因为崩溃或其他原因而无法执行,那 ...

  9. MySQL/MariaDB中的事务和事务隔离级别

    本文目录:1.事务特性2.事务分类 2.1 扁平事务 2.2 带保存点的扁平事务 2.3 链式事务 2.4 嵌套事务 2.5 分布式事务3.事务控制语句4.显式事务的次数统计5.一致性非锁定读(快照查 ...

随机推荐

  1. 从linux源码看socket的阻塞和非阻塞

    从linux源码看socket的阻塞和非阻塞 笔者一直觉得如果能知道从应用到框架再到操作系统的每一处代码,是一件Exciting的事情. 大部分高性能网络框架采用的是非阻塞模式.笔者这次就从linux ...

  2. Linux 重装MySQL

    1.首先查看当前MySQL的安装情况,查找之前是否安装了MySQL rpm -qa|grep -i mysql 可以看到如下图: 因为我是使用的宝塔面板一键安装的LAMP,所以显示安装了bt-mysq ...

  3. java之单点登录(SSO)

    单点登录(SSO):SSO是指在多个应用系统中个,用户只需要登陆一次就可以访问所有相互信任的应用系统.它包括可以将这次主要的登录映射到其他应用中用于同一用户的登陆的机制. SSO的实现过程: 通过上述 ...

  4. Python脚本批量修改服务器密码

    搭建环境 centos 7.4 使用脚本 python 批量修改connect用户的密码 生成密码为随机密码 保存为xls文档   passwd_chang #!/usr/bin/env python ...

  5. 没了IDE,你的Java项目还能Run起来吗~

    计算机只能识别机器码0101...编程语言->能执行的机器码 需要经过 预处理->编译->汇编->链接->机器码过程.一个语言处理系统的示意图如下: 编译器 是将源语言程 ...

  6. 20184302 2019-2020-2 《Python程序设计》实验四报告

    20184302 2019-2020-2 <Python程序设计>实验四报告 课程:<Python程序设计> 班级: 1843 姓名: 李新锐 学号:184302 实验教师:王 ...

  7. javascript 面向对象学习(二)——原型与继承

    什么是原型? 首先我们创建一个简单的空对象,再把它打印出来 var example = {} console.log(example) 结果如下: { __proto__: { constructor ...

  8. php的ts和nts选择

    TS(Thread-Safety)即线程安全,多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用.不会出现数据不一致或者数据 ...

  9. virtualbox 基于nat模式搭建局域网并且和宿主机通信

    1.VIRTUALbox 2.两台虚拟机,设置网络为DHCP方式 检查文件确认是dhcp模式不是的百度搜索修改:/etc/sysconfig/network-scripts/ifcfg-enps3(网 ...

  10. 完美解决PYQT5登录界面跳转主界面方法

    该问题,有很多种方法,但是很多方法要么这个有问题,要么那个有问题,最后终于找到一种没问题的方法.记录一下: Login.py(登录窗口)文件 import sys from PyQt5 import ...