事务是什么

百度百科是这么定义的:

事务(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. QT的字符编码

    QString编码:UTF-16 QString内部保存的数据就是QChar数组,是Unicode编码(utf16),在字符显示,操作的时候都是基于Unicode. QString构造时默认采用Lat ...

  2. Dart 2.18 正式发布

    互操作性增强.平台特定的网络组件.优化类型推断,以及空安全语言里程碑的近期更新 文/ Michael Thomsen, Google Flutter & Dart 产品经理 Dart 2.18 ...

  3. 来点基础的练习题吧,看见CSDN这类基础的代码不多

    来点基础的练习题吧,看见CSDN这类基础的代码不多 //正三角形 void ex03(){ int i,k=0, rows, space; printf("请输入三角形的层次:") ...

  4. Python数据科学手册-Numpy入门

    通过Python有效导入.存储和操作内存数据的技巧 数据来源:文档.图像.声音.数值等等,将所有的数据简单的看做数字数组 非常有助于 理解和处理数据 不管数据是何种形式,第一步都是 将这些数据转换成 ...

  5. (二)JPA 连接工厂、主键生成策略、DDL自动更新

    (一)JPA的快速入门 2.JPA连接工厂 通过之前的 代码 实现已经清楚的发现了整个的JPA实现步骤,但是这个步骤似乎有一些繁琐了,毕竟最终所关心的一定是EntityManager对象实例,而要想获 ...

  6. 获取Docker容器名称和ID

    docker ps --format "{{.Names}}" docker ps -q

  7. 基于ELK Nginx日志分析

    配置Nginx 日志 Nginx 默认的access 日志为log格式,需要logstash 进行正则匹配和清洗处理,从而极大的增加了logstash的压力 所以我们Nginx 的日志修改为json ...

  8. 为不同的用户生成不同的 Kibana 界面

    文件转载自:https://elasticstack.blog.csdn.net/article/details/109593613

  9. DDD-领域驱动(四)-使用IMediator 实现领域事件

    领域事件是指:一个领域中出触发的 集成事件是指:多个微服务之前产生的事件 核心对象 IMediator INotification INotificationHandler 引入:IMediator ...

  10. 微信DAT文件转JPG图片(图片恢复)

    微信电脑版现在已经是日常工作生活必不可少的工具,有时候删除了聊天记录或者被系统清理软件清理了,但还想查看曾经的微信聊天图片. 这个时候辛辛苦苦找到了文件,却发现无法查看,因为微信电脑版为了保护我们的隐 ...