1.什么是事务

数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性。事务是数据库运行中的逻辑工作单位,由DBMS中的事务管理子系统负责事务的处理。

2.事务的ACID属性

2-1.原子性(Atomicity)

一个事务(Transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

2-2.一致性(Consistency)

一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。

2-3.隔离性(Isolation)

数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(Read committed)、可重复读(Repeatable read)和串行化(Serializable)。

2-4.持久性(Durability)

事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

在 MySQL 命令行的默认设置下,事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作。因此要显式地开启一个事务务须使用命令 BEGIN 或 START TRANSACTION,或者执行命令 SET AUTOCOMMIT=0,用来禁止使用当前会话的自动提交。

3.事务控制语句

  • BEGIN(START TRANSACTION): 显式地开启一个事务。
  • ROLLBACK(ROLLBACK WORK): 回滚会结束用户的事务,并撤销正在进行的所有未提交的修改。
  • COMMIT(COMMIT WORK): 提交事务,并使已对数据库进行的所有修改成为永久性的。
  • SET AUTOCOMMIT=0/1: 禁止自动提交/开启自动提交(默认)

4.隔离级别

4-1.操作隔离级别SQL

mysql> select @@tx_isolation; --查看当前数据库的隔离级别

mysql> set [gloabl | session] trasaction isoslation level 隔离级别名称; -- 设置隔离级别
-- 或
mysql> set tx_isolation='read-uncommitted'; -- 设置隔离级别

4-2.四种隔离级别

隔离级别名称 脏读 不可重复读 幻读
READ-UNCOMMITTED
READ-COMMITTED
REPEATABLE-READ
SERIALIZABLE

MySQL默认的隔离级别是: REPEATABLE-READ

4-3.脏读、不可重复读、幻读

4-3-1.脏读

(针对未提交数据)如果事务A中对数据进行了更新,但事务还没有提交,事务B可以"看到"该事务没有提交的更新结果,这样造成的问题就是,如果事务A回滚,那么,事务B在此之前所"看到"的数据就是一笔脏数据。

4-3-2.不可重复读

(针对其他提交前后,读取数据本身的对比)不可重复读取是指同一个事务在整个事务过程中对同一笔数据进行读取,每次读取结果都不同。如果事务A在事务B的更新操作之前读取一次数据,在事务B的更新操作之后再读取同一笔数据一次,两次结果是不同的,所以,Read Uncommitted也无法避免不可重复读取的问题。

流程描述

  1. 事务A开启事务
  2. 事务B开启事务
  3. 事务A读取一条数据
  4. 事务B更新事务A读取的数据
  5. 事务B提交事务
  6. 事务A读取到了事务B更新的数据
  7. 事务A提交事务

简单说就是在一个事务中两次读取的数据不一样。

4-3-3.可重复读

可重复读(Repeatable Read),当使用可重复读隔离级别时,在事务执行期间会锁定该事务以任何方式引用的所有行。因此,如果在同一个事务中发出同一个SELECT语句两次或更多次,那么产生的结果数据集总是相同的。因此,使用可重复读隔离级别的事务可以多次检索同一行集,并对它们执行任意操作,直到提交或回滚操作终止该事务。

简单说就是在一个事务中两次读取的数据一定相同。

4-3-4.幻读

多次读取一个范围内的记录(包括直接查询所有记录结果或者做聚合统计), 发现结果不一致(标准档案一般指记录增多, 记录的减少应该也算是幻读)。

与不可重复读的区别是:

  • 不可重复读:针对的是某条数据的某个列的改变
  • 幻读: 针对的是新增或删除行数的改变

其实对于幻读, MySQL的InnoDB引擎默认的RR级别已经通过MVCC自动帮我们解决了, 所以该级别下, 你也模拟不出幻读的场景; 退回到RC隔离级别的话, 你又容易把幻读和不可重复读搞混淆, 所以这可能就是比较头痛的点吧!

具体可以参考《高性能MySQL》对RR隔离级别的描述, 理论上RR级别是无法解决幻读的问题, 但是由于InnoDB引擎的RR级别还使用了MVCC, 所以也就避免了幻读的出现!

MVCC虽然解决了幻读问题, 但严格来说只是解决了部分幻读问题。

复现问题步骤(数据库隔离级别为RR):

  1. 开启事务A
  2. 开启事务B
  3. 在事务B中查询表A中的所有数据
  4. 在事务A中向表A中插入一条数据(insert into category(category_id, name, last_update) value(20, 'Admin', CURRENT_TIMESTAMP);
  5. 在事务B中查询表A的所有数据,并没有列出事务B刚刚插入的数据(避免了幻读)
  6. 提交事务A
  7. 在事务B中继续查询表A的所有数据,还是没有列出事务B刚刚插入的数据(避免了幻读)
  8. 在事务B中向表A中插入一条数据(insert into category(category_id, name, last_update) value(20, 'Admin', CURRENT_TIMESTAMP);
  9. 事务B会报错: ERROR 1062 (23000): Duplicate entry '20' for key 'PRIMARY'
  10. 提交事务B

这说明什么?

The snapshot of the database state applies to SELECT statements within a transaction, not necessarily to DML statements. If you insert or modify some rows and then commit that transaction, a DELETE or UPDATE statement issued from another concurrent REPEATABLE READ transaction could affect those just-committed rows, even though the session could not query them. If a transaction does update or delete rows committed by a different transaction, those changes do become visible to the current transaction.

个人认为应该翻译为: 数据库状态的快照适用于事务中的SELECT语句, 而不一定适用于所有DML语句。 如果您插入或修改某些行, 然后提交该事务, 则从另一个并发REPEATABLE READ事务发出的DELETE或UPDATE语句就可能会影响那些刚刚提交的行, 即使该事务无法查询它们。 如果事务更新或删除由不同事务提交的行, 则这些更改对当前事务变得可见。

浅谈MySQL事务及隔离级别的更多相关文章

  1. MySQL事务学习-->隔离级别

    MySQL事务学习-->隔离级别 6 事务的隔离级别 设置的目的 在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别. 数据库是要被广大客户所共享访问的,那么在数据库操作过程中 ...

  2. MySQL事务及隔离级别详解

    MySQL事务及隔离级别详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MySQL的基本架构 MySQL的基本架构可以分为三块,即连接池,核心功能层,存储引擎层. 1> ...

  3. MySql事务及隔离级别

    在数据库中,所谓事务是指作为单个逻辑工作单元执行的一系列操作. 事务的操作: 先定义开始一个事务,然后对数据作修改操作, 这时如果提交(COMMIT),这些修改就永久地保存下来 如果回退(ROLLBA ...

  4. MySql事务的隔离级别及作用

    逻辑工作单元遵循一系列(ACID)规则则称为事务. 原子性:保证事务是一系列的运作,如果中间过程有一个不成功则全部回滚,全部成功则成功.保证了事务的原则性. 一致性:一致性指的是比如A向B转100块钱 ...

  5. [转]MySQL事务学习-->隔离级别

    From : http://blog.csdn.net/mchdba/article/details/12837427 6 事务的隔离级别 设置的目的 在数据库操作中,为了有效保证并发读取数据的正确性 ...

  6. MySQL事务及隔离级别(读书小结)

    标签: MySQL事务 隔离 0.什么是事务? 事务是指MySQL的一些操作看做是一个不可分割的执行单元.事务的特点是要么所有操作都执行成功,要么一个都不执行.也就是如果一个事务有操作执行失败,那么就 ...

  7. MySQL事务的隔离级别

    为什么需要隔离 当多个线程都开启事务操作数据库中的数据时,数据库系统要能进行隔离操作,以保证各个线程获取数据的准确性,在介绍数据库提供的各种隔离级别之前,我们先看看如果不考虑事务的隔离性,会发生的几种 ...

  8. mysql 事务、隔离级别

    一.事务的四大特性(ACID) 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节.事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有 ...

  9. MySQL——事务ACID&隔离级别

    数据库事务ACID&隔离级别 什么是事务 事务是用户定义的一个数据库操作序列.这些操作要么全执行,要么全不执行,是一个不可分割的工作单元.在关系型数据库中,事务可以是一条SQL语句,也可以是一 ...

随机推荐

  1. video兼容--可用

    兼容ie6,7,8,但是播放器会卡顿黑屏<!DOCTYPE html> <html lang="en"> <head> <meta cha ...

  2. 多线程Task

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  3. canvas实现刮刮乐

    效果展示 源码下载

  4. SQL server 数据库的数据完整性

    存储在数据库中的所有数据值均正确的状态.如果数据库中存储有不正确的数据值,则该数据库称为已丧失数据完整性. 详细释义 数据库中的数据是从外界输入的,而数据的输入由于种种原因,会发生输入无效或 错误信息 ...

  5. for循环执行时在,每执行一次for循环中弹出提示框,延时问题

    在需求中,ajax的返回值,根据数组内容的长度去做循环,每循环一次弹出提示框,发现for循环的执行速度非常之快,想到了延时,但是在for循环中延时并不能解决这个问题. 查到setTimeout的递归处 ...

  6. ROS进阶学习手记 7.2 -- RViz仿真实例2:Create SmartCar

    上一节玩了 exbot 在RViz里的仿真控制,这里我们用urdf文件写个自己的小车模型,ref: http://blog.csdn.net/hcx25909/article/details/8904 ...

  7. 插件:★★★ !!!图片懒加载 lazyload.js 、 jquery.scrollLoading.js

    插件:图片懒加载 jquery.lazyload.js 2016-3-31 插件说明:http://www.w3cways.com/1765.html (小插件,好用) 下载地址: https://r ...

  8. hive 动态分区实现 (hive-1.1.0)

    笔者使用的hive版本是hive-1.1.0 hive-1.1.0动态分区的默认实现是只有map没有reduce,通过执行计划就可以看出来.(执行计划如下) insert overwrite tabl ...

  9. PHP微信公共号自定义菜单。

    /**微信生成菜单 * [addMennu description] */ public function addMennu(){ $token = $this->getToken(); $ur ...

  10. 如何消除“为帮助保护您的安全,Internet Explorer 已经限制此文件显示可能访问您计算机

    如何消除“为帮助保护您的安全,Internet Explorer 已经限制此文件显示可能访问您计算机的活动内容.单击此处查看选项...”每次打开都出现警告音,可以打开浏览器的工具--> Inte ...