事务是什么

百度百科是这么定义的:

事务(Transaction),一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元。在关系数据库中,一个事务可以是一条SQL语句,一组SQL语句或整个程序。

维基百科:

数据库事务表示在数据库管理系统内针对数据库执行的工作单元,该工作单元以独立于其他事务的连贯可靠的方式进行处理。事务通常表示数据库中的任何更改。数据库环境中的事务有两个主要目的:

  1. 提供可靠的工作单元,允许从故障中正确恢复,即使在系统故障的情况下也能保持数据库的一致性。

    例如,当执行过早和意外停止(完全或部分)时,在这种情况下,对数据库的许多操作仍未完成,状态不明确。

  2. 在并发访问数据库的程序之间提供隔离。如果不提供这种隔离,则程序的结果可能是错误的。在数据库中以一致模式完成的任何逻辑计算都称为事务。一个例子是从一个银行账户转移到另一个银行账户:完整的交易需要减去从一个账户转账的金额,然后将相同的金额添加到另一个账户。

对比来看,维基百科中的阐述更值得分析一下:

  1. 数据库事务是什么?

    数据库事务表示在数据库管理系统内针对数据库执行的工作单元;事务通常表示数据库中的任何更改。

也就是说,数据库事务是针对于数据库中的一组操作。这一组操作根据应用场景的不同,可能一个SQL搞定,也可能需要两个,甚至N个。这多个SQL操作,被当成一个工作单元,它是个整体。维基百科还举了一个我们很熟的例子:银行转账,A给B转账,对应了两个SQL操作,A的钱减少,B的钱增加,但这个是一件事,不能有中间态,即使转账失败了,A、B的钱还是原样。

  1. 事务的作用是什么?

    提供可靠的工作单元,允许从故障中正确恢复。

    在并发访问数据库的程序之间提供隔离。

    在数据库中以一致模式完成的任何逻辑计算都称为事务。

事务要让工作单元可靠,即使发生故障,也能正确恢复;如果有多个线程访问数据库时,每个线程之间互不影响,他们各自的操作在自己看来都是正常的;因此,事务的目的就是要维持工作单元的一致性。

可以总结出事务的四个特性,我们把它们称作ACID:

  1. 原子性(Atomicity):原子性保证每个事务都被视为一个“单元”,它要么完全成功,要么完全失败。如果事务中一个SQL执行失败,则其他已执行的sql语句都会回滚,数据回退到事务前的状态。
  2. 一致性(Consistency):一致性确保事务只能将数据库从一个一致状态带到另一个一致状态,保持数据库不变性。也就是所有写入数据库的数据在既定的规则下,都是有效的。
  3. 隔离性(Isolation):隔离性是指,事务内部的操作与其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
  4. 持久性(Durability):事务一旦提交,数据能存入硬盘,永久保存。

一句话总结下事务,事务将数据库中的一组操作看成一个工作单元,它要么全部成功,要么全部失败,目的是为保证数据的一致性。

按照严格的标准,只有同时满足ACID特性才是事务;但是在各大数据库厂商的实现中,真正满足ACID的事务少之又少。例如MySQL的NDB Cluster事务不满足持久性和隔离性;InnoDB默认事务隔离级别是可重复读,不满足隔离性;Oracle默认的事务隔离级别为READ COMMITTED,不满足隔离性......因此,与其说ACID是事务必须满足的条件,不如说它们是衡量事务的四个维度。

开启事务

MySQL默认是自动提交事务的,可以用sql查询:

select @@autocommit;

也就是说,每执行完一条sql数据库就会自动帮我们提交事务,但在实际情况中,一个业务操作会对应多条sql,不可能每执行完一条sql就提交,事务有多条sql时,需要执行完最后一条才能提交或者回滚。

MySQL中手动开启事务有2种方式:

start transaction; -- 使用begin也可以

或者

set autocommit = 0;

手动开启事务或者设置事务手动提交后,每次执行完一组sql都需要手动commit或者rollback才能生效。如果你一直没有提交,或者一直没回滚会怎么样?那肯定是,你后面的所有sql操作就跟之前的操作在一个事务里,事务没有提交,根据事务不同的隔离级别,数据的查询会呈现不一样的结果。

事务隔离级别

如果说ACID是事务的标准,那数据库的隔离级别就是为了达到这个标准而采用的策略。MySQL事务隔离级别有四种,而每一种隔离级别又存在不同的事务问题。严格的说,只有serializable这种事务隔离级别,才真正满足ACID,但是serializable会强制事务串行执行(类似Java的synchronized串行锁),就是如果一个线程在还没有提交事务,另一个线程就会一直等待,直到前一个线程提交事务,它才能继续执行。它并发效率很低,实际使用的很少。而其他事务隔离级别,又存在着各自不同的事务问题。

隔离级别 脏读 不可重复度 幻读
read uncommitted(读未提交)
read committed(读已提交) ×
repeatable read(可重复读) × ×
serializable(串行化) × × ×

查看事务隔离级别:

 select @@transaction_isolation;

设置事务隔离级别:

set [session|global] transaction isolation level {read uncommitted | read committed | repeatable read | serializable}

session代表当前会话,global代表全局会话。设置全局事务隔离级别:

set global transaction isolation level read uncommitted;

脏读

事务A读到事务B未提交的数据(脏数据),这种现象叫脏读。

不可重复度

在事务A中先后两次读取同一个数据,两次读取的结果不一样,这种现象称为不可重复读。脏读与不可重复读的区别在于:前者读到的是其他事务未提交的数据,后者读到的是其他事务已提交的数据。

幻读

在事务A中按照某个条件先后两次查询数据库,两次查询结果的条数不同,这种现象称为幻读。不可重复读与幻读的区别可以通俗的理解为:前者是数据变了,后者是数据的行数变了。

总结

事务具有ACID属性,数据库不同的事务隔离级别存在各自的事务问题,这也是面试常问的问题。

理解MySQL事务的更多相关文章

  1. 深入理解MySql事务

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

  2. 理解MySql事务隔离机制、锁以及各种锁协议

    一直以来对数据库的事务隔离机制的理解总是停留在表面,其内容也是看一遍忘一边.这两天决定从原理上理解它,整理成自己的知识.查阅资料的过程中发现好多零碎的概念假设串起来足够写一本书,所以在这里给自己梳理一 ...

  3. 五分钟后,你将真正理解MySQL事务隔离级别!

    什么是事务? 事务是一组原子性的SQL操作,所有操作必须全部成功完成,如果其中有任何一个操作因为崩溃或其他原因无法执行,那么所有的操作都不会被执行.也就是说,事务内的操作,要么全部执行成功,要么全部执 ...

  4. Mysql事务及行级锁的理解

    在最近的开发中,碰到一个需求签到,每个用户每天只能签到一次,那么怎么去判断某个用户当天是否签到呢?因为当属表设计的时候,每个用户签到一次,即向表中插入一条记录,根据记录的数量和时间来判断用户当天是否签 ...

  5. 深入理解 MySQL ——锁、事务与并发控制

    本文首发于vivo互联网技术微信公众号 mp.weixin.qq.com/s/JFSDqI5ya… 作者:张硕 本文对 MySQL 数据库中有关锁.事务及并发控制的知识及其原理做了系统化的介绍和总结, ...

  6. 对mysql事务提交、回滚的错误理解

    一.起因 begin或者START TRANSACTION开始一个事务 rollback事务回滚 commit 事务确认 人们对事务的解释如下:事务由作为一个单独单元的一个或多个SQL语句组成,如果其 ...

  7. 深入理解MySQL的并发控制、锁和事务【转】

    本文主要是针对MySQL/InnoDB的并发控制和加锁技术做一个比较深入的剖析,并且对其中涉及到的重要的概念,如多版本并发控制(MVCC),脏读(dirty read),幻读(phantom read ...

  8. [转帖]2019-03-26 发布 深入理解 MySQL ——锁、事务与并发控制

    深入理解 MySQL ——锁.事务与并发控制 https://segmentfault.com/a/1190000018658828 太长了 没看完.. 数据库 并发  mysql 639 次阅读   ...

  9. [转帖]深入理解 MySQL—锁、事务与并发控制

    深入理解 MySQL—锁.事务与并发控制 http://www.itpub.net/2019/04/28/1723/ 跟oracle也类似 其实所有的数据库都有相同的机制.. 学习了机制才能够更好的工 ...

  10. 理解MySQL数据库事务-隔离性

    Transaction事务是指一个逻辑单元,执行一系列操作的SQL语句. 事务中一组的SQL语句,要么全部执行,要么全部回退.在Oracle数据库中有个名字,叫做transaction ID 在关系型 ...

随机推荐

  1. linux使用iptables屏蔽ip地址

    一.iptables命令介绍: netfilter/iptables(简称为iptables)组成Linux平台下的包过滤防火墙,与大多数的Linux软件一样,这个包过滤防火墙是免费的,在安装系统的时 ...

  2. 6、Arrays类

    Arrays类 Arrays里面包含了一系列静态方法,用于管理或操作数组(比如排序和搜索) 常用方法 toString 返回数组的字符串形式 Arrays.toString(arr) Integer[ ...

  3. YAML资源清单

    YAML 文件基本语法格式 在 Docker 环境下面我们是直接通过命令 docker run 来运行我们的应用的,在 Kubernetes 环境下面我们同样也可以用类似 kubectl run 这样 ...

  4. Logstash:运用 memcache 过滤器进行大规模的数据丰富

    文章转载自:https://blog.csdn.net/UbuntuTouch/article/details/106915969 理论上也可以使用redis,有待实践

  5. docker相关总结

    Docker 的相关使用记录 一.安装docker linux环境使用yum命令安装docker 第一步:确保自己的虚拟机没有安装过docker,如果安装过的需要将原先的docker进行卸载,命令如下 ...

  6. 在 WPF 中实现融合效果

    1. 融合效果 融合效果是指对两个接近的元素进行高斯模糊后再提高对比度,使它们看上去"粘"在一起.在之前的一篇文章中,我使用 Win2D 实现了融合效果,效果如下: 不过 Win2 ...

  7. P7361 「JZOI-1」拜神 (字符串)

    题意: 给一个串,\(Q\) 次询问区间 \([l,r]\) 中至少出现两次的子串的最大长度. 写LCT是什么东东 以下做法很经典: 先求出 SA 以及 height 数组,然后按 height 从大 ...

  8. C++面向对象编程之虚指针、虚表

    1.当编译器看到一个函数调用,有2个考量:静态绑定or动态绑定 静态绑定是"call xxx",xxx 是表示地址,call 是汇编语言的一个动作,它一定会调用到某个地址: 当符合 ...

  9. LOJ139 树链剖分

    题目 感觉这已经不能说是模板了吧...... 解析: 难点在于换根后对子树进行的操作,设rt为当前根节点,u为操作子树: u=rt时,就是对整棵树操作,没事么好说的. rt不在u的子树范围内,操作对象 ...

  10. JDK中自带的JVM分析工具

    目录 一.业务背景 二.Jdk-Bin目录 三.命令行工具 1.jps命令 2.jinfo命令 3.jstat命令 4.jstack命令 5.jmap命令 四.可视化工具 1.jconsole 2.v ...