事务概念

  事务可由一条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. jquery attribute选择器 语法

    jquery attribute选择器 语法 作用:[attribute] 选择每个带有指定属性的元素.可以选取带有任何属性的元素(对于指定的属性没有限制). 语法:$("[attribut ...

  2. LA 2797

    题目链接 题意:训练指南283页: #include <iostream> #include <cstdio> #include <cstring> #includ ...

  3. hdu 2553 八皇后问题 基础

    题意:给你一个n*n的棋盘,要求放n个皇后: <span style="font-size:18px;">#include <iostream> #incl ...

  4. hdu_1059(多重背包)

    多重背包的讲解: 多重背包问题https://blog.csdn.net/yandaoqiusheng/article/details/84782655 ; i <= n; i++) { int ...

  5. Android重写HorizontalScrollView模仿ViewPager效果

    Android提供的ViewPager类太复杂,有时候没有必要使用,所以重写一个HorizontalScrollView来实现类似的效果,也可以当做Gallery来用 思路很简单,就是重写onTouc ...

  6. win10 exe如何添加或禁用开机自启动项

    一.添加开机自启动 1,先打开存放自启动软件文件的文件夹 方法①:在文件搜索框中输入或粘贴以下地址: C:\ProgramData\Microsoft\Windows\Start Menu\Progr ...

  7. python学习之路(18)

    返回函数 函数作为返回值 高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回. 我们来实现一个可变参数的求和.通常情况下,求和的函数是这样定义的: >>> def a(* ...

  8. python学习之路(9)

    函数的参数 定义函数的时候,我们把参数的名字和位置确定下来,函数的接口定义就完成了.对于函数的调用者来说,只需要知道如何传递正确的参数,以及函数将返回什么样的值就够了,函数内部的复杂逻辑被封装起来,调 ...

  9. RabbitMq运行原理浅析

    转载:https://blog.csdn.net/Evankaka/article/details/80977027 1.RabbitMq简介     AMQP,即Advanced Message Q ...

  10. 2019java第十二周课程总结

    本周主要还是学习图形界面 各种容器使用方法 如下代码: package text10; import java.awt.*; import java.io.File; import javax.swi ...