事务概念

  事务可由一条sql或者一组sql组成。事务是访问并更新数据库中各种数据项的一个程序执行单元。

  事务会把数据库从一种一致状态转换为另一种一致状态。在数据提交工作时,可以确保要么所有修改都已经保存了,要么所有修改都不保存。

  事务需要满足ACID特性(不同厂商、mysql不同的存储引擎并非严格遵守ACID)。

ACID特性

  原子性(atomicity)

    事务是不可分割的工作单位,事务中的多个操作是一个整体,要么都做,要么都不做

  一致性(consistency)

    一致性指事务将数据库从一种一致状态转变为下一种一致状态。事务开始之前和结束之后,数据库的完整性约束并没有被破坏。如果事务中某个动作失败了,系统可以自动撤销事务并返回事务开始之前的状态。

  隔离性(isolation)

    多个事务之间彼此隔离,通过锁实现。一个事务对数据的操作在提交前是对其他事务隐藏的,隔离的。

  持久性(durability)

    事务一旦提交,其结果就是永久性的。就是发生宕机等故障,数据库也能将提交的数据恢复。mysql通过redo log实现。

  

   原子性由redo log(重做日志)实现;

   一致性由redo log和undo log(回滚段)实现;

   持久性由redo log实现;

   隔离性由锁实现。

事务隔离级别

  大部分数据库都没有提供真正的隔离性,隔离性可以保证正确性但却无法保证性能。

  RU(Read Uncommitted,读未提交)

    一个事务可以读到其他事务已修改但尚未提交的数据,脏读。安全性最低,并发度(无锁)最高。

  RC(Read Committed,读已提交)

    一个事务中只可以读到已提交的数据,过程中如果数据被其他事务修改并提交,则当前事务再次读时,读到的是已修改后的数据,即不可重复读。

  RR(Repeatable Read,可重复读)

    一个事务只读取当前事务开始时提交的数据,过程中如果数据被其他事务修改并提交,则无影响;事务开始时不存在的数据,被其他事务提交后,当前事务可以读到,即幻读(不同数据库实现不同,mysql在RR隔离级别下使用next-key锁解决了幻读问题)。

  Serializable(序列化/串行)

    事务串行执行,安全性最高,并发度最低。

  

  概念

    脏读

      脏数据指未提交的数据

      脏读是当前事务读到了其他事务中未提交的数据,即读到了脏数据

    不可重复读(侧重update)

      在一个事务中对同一数据的两次/多次读取,读到的数据不一样,即不可重复读

    幻读(侧重insert)

      在一个事务中已经检查过不存在的记录,再次查询时却已存在

  隔离性的实现-锁 

    行锁、间隙所、Next-key锁、Previous-key锁、页锁、意向锁、表锁、MDL(元数据)锁

      行锁

        顾名思义,在数据记录上加的锁,分为X锁和S锁。

      间隙锁

        锁住一段区间,range,不包括当前记录。

      行锁+间隙锁=Next-key锁/Previous-key锁      

        包括当前记录

      意向锁

      

      

      

    

    行级锁分为X(写/独占)锁、S(读/共享)锁

      

    一致性锁定读(加锁,根据情况,阻塞其他加锁请求)

      通过加锁的方式

      select ... for update; 加X锁

      select ... lock in share mode; 加S锁

    一致性非锁定读(不加锁,不阻塞)

      mvcc(多版本并发控制,通过undo log实现)

        

        

    死锁

      死锁是指两个或者两个以上事务在执行过程中,因争夺锁资源而造成的一种互相等待的现象

      解决方案:超时、锁等待图

演示

  准备

    测试表建表sql

      CREATE TABLE t_a (
        id INT (10) NOT NULL,
        content VARCHAR (10) NOT NULL,
        PRIMARY KEY (id)
      ) ENGINE = INNODB;

    开启3个mysql终端,2个用来测试(以下统一使用t1,t2名称代替),1一个用来查看锁信息(以下统一使用info3名称代替)

    修改事务隔离级别命令

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

  隔离级别

    RU隔离级别下脏读

      设置事务隔离级别为RU

        

      t1中开启事务,向t_a表中插入一条数据,不要提交

        

      t2中开启事务,读t_a表的数据,读到了脏数据(未提交的数据)

        

        如果t2中以此数据作为执行后续逻辑的判断条件,则可能会导致业务错误或者数据混乱。

      t1中rollback

        

      t2中再次查询,已经查不到了

        

    RC隔离级别下无脏读

      设置事务隔离级别为RC

        

       t1中开启事务并向t_a表中插入一条记录,但是不提交

        

       t2中开启事务,查询t_a表数据,发现不会查询出未提交的数据

        

       提交t1中的事务

        

       t2中再次查询,可以查询到已提交的数据,说明无脏读问题

        

    RC隔离级别下不可重复读问题

       先向t_a表中插入一条记录

        

       t1中开启事务,并查询这条记录

        

       t2中开启事务修改这条记录,并提交

        

       t1中再次查询这条记录,发现数据不一致,也就是不可重复读

        

    

    RR隔离级别下可重复读

      设置事务隔离级别为RR

        

      t1中开启事务,并查询t_a表中记录

        

      t2中开启事务,修改表中记录,并提交

        

      t1中再次查询t_a表中的记录,发现数据无变化,即可重复读

        

  死锁 

    t1开启事务,对t_a的id为1的记录加X锁

      

    t2中开启事务,对t_a的id为2的记录加X锁

      

    t1中申请t_a的id为2的记录的X锁,被阻塞(t2中的事务正在持有锁)

      

    t2中申请t_a的id为1的记录的X锁,报错,提示死锁

      

  X锁、S锁

    阻塞

       t1中开启事务对t_a表中id为1的记录加X锁

        

       t2中开启事务对t_a表中id为1的记录申请加S锁,被阻塞

        

       info3中查询锁信息

        

        

    MVCC

       t1中开启事务对t_a表中id为1的记录加X锁

        

       t2中开启事务读t_a表中id为1的记录,未阻塞

        

  实例 

    

    上图中并发情况下,两个线程开启两个事务,同时执行到if代码行,则返回的结果都是true,会造成重复插入。

    一般的解决方案有:

      unique key

      insert into ... select...

        如下面的sql,

        insert into t_a
        select 3, '3'
        from dual
        where not exists (
        select 0 from t_a where content = '3'
        );

        会对t_a表中content=3的记录加锁,阻塞其他插入content='3'的请求,从而避免重复插入

        

    

Mysql事务特性的更多相关文章

  1. Mysql 事务特性和隔离级别

    事务的特性 原子性(Atomicity) 一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节.事务在执行过程中发生错误,会被回滚(Rollback)到 ...

  2. MySQL · 引擎特性 · InnoDB 事务子系统介绍

    http://mysql.taobao.org/monthly/2015/12/01/ 前言 在前面几期关于 InnoDB Redo 和 Undo 实现的铺垫后,本节我们从上层的角度来阐述 InnoD ...

  3. 网络协议 finally{ return问题 注入问题 jdbc注册驱动问题 PreparedStatement 连接池目的 1.2.1DBCP连接池 C3P0连接池 MYSQL两种方式进行实物管理 JDBC事务 DBUtils事务 ThreadLocal 事务特性 并发访问 隔离级别

    1.1.1 API详解:注册驱动 DriverManager.registerDriver(new com.mysql.jdbc.Driver());不建议使用 原因有2个: >导致驱动被注册2 ...

  4. 深入学习MySQL事务:ACID特性的实现原理

    事务是MySQL等关系型数据库区别于NoSQL的重要方面,是保证数据一致性的重要手段.本文将首先介绍MySQL事务相关的基础概念,然后介绍事务的ACID特性,并分析其实现原理. MySQL博大精深,文 ...

  5. MySQL事务及ACID特性

    一.事物 1.定义:事务是访问和更新数据库的程序执行单元,事务中包含一条或者多条SQL语句,这些语句要么全部执行成功,要么都不执行. 在MySQL中,事务支持是在引擎层实现的,MySQL是一个支持多引 ...

  6. 一文说尽MySQL事务及ACID特性的实现原理

    MySQL 事务基础概念 事务(Transaction)是访问和更新数据库的程序执行单元:事务中可能包含一个或多个 sql 语句,这些语句要么都执行,要么都不执行.作为一个关系型数据库,MySQL 支 ...

  7. MySQL InnoDB如何保证事务特性

    如果有人问你"数据库事务有哪些特性"?你可能会很快回答出原子性.一致性.隔离性.持久性即ACID特性.那么你知道InnoDB如何保证这些事务特性的吗?如果知道的话这篇文章就可以直接 ...

  8. 个人MySQL的事务特性原理学习笔记总结

    目录 个人MySQL的事务特性原理笔记总结 一.基础概念 2. 事务控制语句 3. 事务特性 二.原子性 1. 原子性定义 2. 实现 三.持久性 1. 定义 2. 实现 3. redo log存在的 ...

  9. MySQL 学习笔记(一)MySQL 事务的ACID特性

    MySQL事务是什么,它就是一组数据库的操作,是访问数据库的程序单元,事务中可能包含一个或者多个 SQL 语句.这些SQL 语句要么都执行.要么都不执行.我们知道,在MySQL 中,有不同的存储引擎, ...

随机推荐

  1. SELinux 对nginx访问目录的影响

    centos新装的系统,用yum 安装的nginx . 因用yum 安装的nginx 默认目录在/usr下面. 当SELinux开启时,将会禁止访问设置在其他路径下的地址.比如我设置server 中 ...

  2. vue2.0 移动端,下拉刷新,上拉加载更多 封装组件

    前言 在做移动端的避免不了 下拉刷新,上拉加载 直接上代码吧,哈哈 组件里: <template lang="html"> <div class="yo ...

  3. http学习--常用请求方法和响应状态码

    常用的http请求方法: GET方法:请求服务器资源,并返回 POST方法:向指定资源提交数据进行处理请求(比如说表单,上传文件等).数据被包含在请求体中.POST请求可能会导致新的资源建立或已有资源 ...

  4. BZOJ 4154: [Ipsc2015]Generating Synergy KDtree+dfs序

    多组数据真tm恶心~ 把 $dfs$序和深度分别看作横纵坐标,然后用 $KDtree$ 数点就可以了~ #include <cstdio> #include <cstring> ...

  5. mv:移动文件或改名

    mv 命令(move 的缩写),既可以在不同的目录之间移动文件或目录,也可以对文件和目录进行重命名.该命令的基本格式如下: mv [选项] 源文件 目标文件 选项: -f:强制覆盖,如果目标文件已经存 ...

  6. Springboot 系列(十七)迅速使用 Spring Boot Admin 监控你的 Spring Boot 程序,支持异常邮件通知

    1. Spring Boot Admin 是什么 Spring Boot Admin 是由 codecentric 组织开发的开源项目,使用 Spring Boot Admin 可以管理和监控你的 S ...

  7. vue中使用iconfont和在旧有的iconfont中添加新的图标

    todo 使用参考:https://blog.csdn.net/qq_34802010/article/details/81451278 大体步骤是正确的,具体可参考官方文档和下载下来的代码中的dem ...

  8. jmxtrans + influxdb + granafa 监控套件使用手册

    需求说明 随着大数据组件的日益完善,需要随时随地保持各个组件的日常运行,对各个组件的监控势在必行.为了减少运维部门的负担,通过筛选,我们使用 jmxtrans + influxdb + granafa ...

  9. Java中FileOutputStream流的write方法

    本文为大家分享了FileOutputStream流的write方法,供大家参考,具体内容如下 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ...

  10. Mysql 里CHAR和VARCHAR的最大长度及一些注意事项

    先写出结论: Mysql 5中 非空CHAR的最大总长度是255[字节]:非空VARCHAR的最大总长度是65533[字节]. 可空CHAR的最大总长度是254[字节]:可空VARCHAR的最大总长度 ...