什么是事务?

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

事务的结束有两种,当事务中的所有操作全部成功执行时,事务提交。如果其中一个操作失败,将发生回滚操作,撤消之前到事务开始时的所有操作。

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

事务的特性

一个运行良好的事务处理系统,还需要具备四个特性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持续性(Durability)。这四个特性简称为ACID特性。

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

原子性(Atomicity)

一个事务必须被视为一个不可分割的最小逻辑工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚。对于一个事务来说,不可能只执行其中的一部分操作,而不执行其中的另外一部分操作,这就是事务的原子性。

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

一致性(Consistency)

事务执行的结果必须是从一个一致性的状态转换到另外一个一致性的状态。当数据库只包含成功事务提交的结果时,就说数据库处于一致性状态。如果事务因为崩溃或其他原因尚未完成,被迫中断最终事务没有提交,那么事务中所做的修改也不会保存到数据库中。

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

隔离性(Isolation)

通常来说,一个事务的执行不能其它事务干扰。也就是说,一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。后面我们将要讲解隔离级别(Isolation Level)的时候,会发现为什么我们要说“通常来说”是隔离的。

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

持续性(Durability)

事务一旦提交,它对数据库中的数据的修改就应该是永久性的。此时即使系统崩溃,修改的数据也不会丢失。不过,实际上持久性也分很多不同的级别,有些持久性策略能够提供非常强的安全保障,而有些则未必。

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

事务隔离级别

在SQL标准中定义了四种隔离级别,每一种级别都定义了一个事务所做的修改,在另外一个事务内和事务间,哪些是可见的,哪些是不可见的。低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销。

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

未提交读(Read Uncommitted)

未提交读级别中,事务中的修改即使没有提交,对其他事务也是可见的。读取到了事务没有提交的数据,就被成为脏读(Dirty Read)。事务没有提交的数据是很“脏”的,被读取到会引起很多问题。从性能角度上看,未提交读级别不会比其他级别好很多,但缺乏其他级别的好处,所以在实际应用中很少被用到。

为加上深对未提交读级别的理解,让我们看一个脏读的例子,首先设置事务隔离级别为未提交读

mysql> set session transaction isolation level read uncommitted;
Query OK, 0 rows affected (0.00 sec)

再检验一下事务隔离级别:

mysql> select @@tx_isolation;
+------------------+
| @@tx_isolation |
+------------------+
| READ-UNCOMMITTED |
+------------------+
1 row in set, 1 warning (0.00 sec)

左右分别为两个用户,左边是用户A,右边是用户B,时间线从上至下:

#用户A:查询user表,有一条OneMoreStudy的记录		 
mysql> select * from user;  
+----+--------------+  
| id | name |  
+----+--------------+  
| 1 | OneMoreStudy |  
+----+--------------+  
1 row in set (0.00 sec)  
 
  #用户B:开始事务
  mysql> start transaction;
  Query OK, 0 rows affected (0.00 sec)
 
  #用户B:更新user表的一条记录
  mysql> update user set name = 'OMS' where id = 1;
  Query OK, 1 row affected (0.01 sec)
  Rows matched: 1 Changed: 1 Warnings: 0
 
#用户A:查询user表,有一条OMS的记录,脏读  
mysql> select * from user;  
+----+------+  
| id | name |  
+----+------+  
| 1 | OMS |  
+----+------+  
1 row in set (0.00 sec)  
 
  #用户B:提交事务
  mysql> commit;
  Query OK, 0 rows affected (0.00 sec)

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

提交读(Read Committed)

提交读级别中,一个事务开始时,只能查询到其他的事务已经提交的修改。也就是说,一个事务从开始到提交之前,任何的修改对其他的事务都是不可见的。提交读级别基本满足了事务的隔离性。

不过,在同一事务中两次查询之间,有其他事务的修改被提交,那么两次查询到结果可能不相同,这就是不可重复读

为了更好的理解不可重复读,让我们看一个例子,首先设置事务隔离级别为提交读

mysql> set session transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)

再检验一下事务隔离级别:

mysql> select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| READ-COMMITTED |
+----------------+
1 row in set, 1 warning (0.00 sec)

左右分别为两个用户,左边是用户A,右边是用户B,时间线从上至下:

#用户A:开始事务
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec) #用户A:查询user表,有一条OneMoreStudy的记录
mysql> select * from user;
+----+--------------+
| id | name |
+----+--------------+
| 1 | OneMoreStudy |
+----+--------------+
1 row in set (0.00 sec) #用户B:更新user表的一条记录
mysql> update user set name = 'OMS' where id = 1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0 #用户A:查询user表,有一条OMS的记录,不可重复读
mysql> select * from user;
+----+------+
| id | name |
+----+------+
| 1 | OMS |
+----+------+
1 row in set (0.00 sec) #用户A:提交事务
mysql> commit;
Query OK, 0 rows affected (0.00 sec)

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

可重复读(Repeatable Read)

可重复读级别中,保证了在同一个事务中多次读取同样记录的结果是一致的。即使多次读取之间有其他事务对其结果做了修改,同一个事务中多次读取的结果也是一致的。可重复读级别也是MySQL的默认事务隔离级别。

不过,当一个事务在读过某个范围内的记录时,其他事务又在这个范围内插入了新的记录,当之前的事务再一次读取这个范围的记录时,不会读取到新插入的那条记录,这被称为幻读

为了更好的理解幻读,让我们看一个例子,首先把事务隔离级别设置为可重复读

mysql> set session transaction isolation level repeatable read;
Query OK, 0 rows affected (0.00 sec)

再检验一下事务隔离级别:

mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set, 1 warning (0.00 sec)

左右分别为两个用户,左边是用户A,右边是用户B,时间线从上至下:

#用户A:开始事务
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec) #用户A:查询user表,有一条记录
mysql> select * from user;
+----+--------------+
| id | name |
+----+--------------+
| 1 | OneMoreStudy |
+----+--------------+
1 row in set (0.00 sec) #用户B:插入一条数据
mysql> insert into user (name) value ('OneMoreStudy');
Query OK, 1 row affected (0.01 sec) #用户A:查询user表,还是一条记录,幻读
mysql> select * from user;
+----+--------------+
| id | name |
+----+--------------+
| 1 | OneMoreStudy |
+----+--------------+
1 row in set (0.00 sec) #用户A:提交事务
mysql> commit;
Query OK, 0 rows affected (0.00 sec) #用户A:查询user表,两条记录
mysql> select * from user;
+----+--------------+
| id | name |
+----+--------------+
| 1 | OneMoreStudy |
| 2 | OneMoreStudy |
+----+--------------+
2 rows in set (0.00 sec)

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

可串行化(Serializable)

可串行化级别中,强制事务串行执行,是最高的隔离级别。在这个级别中,虽然避免了上面提到的幻读,但是会在读取的每一行上加锁,可能导致大量的超时和锁竞争问题,所以在实际应用中很少被用到。除非,非常需要确保数据一致性并且不要求高并发,可以采用可串行化级别。

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

总结

本文首先简单介绍了事务及其ACID特性,然后着重讲解了事务的四种隔离级别:

  1. 未提交读:事务中的修改即使没有提交,对其他事务也是可见的。
  2. 提交读:事务开始时,只能查询到其他的事务已经提交的修改。
  3. 可重复读:保证在同一个事务中多次读取同样记录的结果是一致的。
  4. 可串行化:强制事务串行执行。
隔离级别 脏读 不可重复读 幻读
未提交读 可能 可能 可能
提交读 不可能 可能 可能
可重复读 不可能 不可能 可能
可串行化 不可能 不可能 不可能

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

五分钟后,你将真正理解MySQL事务隔离级别!的更多相关文章

  1. [51CTO]新说MySQL事务隔离级别!

    新说MySQL事务隔离级别! 事务隔离级别这个问题,无论是校招还是社招,面试官都爱问!然而目前网上很多文章,说句实在话啊,我看了后我都怀疑作者弄懂没!本文所讲大部分内容,皆有官网作为佐证,因此对本文内 ...

  2. 查询mysql事务隔离级别

    查询mysql事务隔离级别 查询mysql事务隔离级别 分类: DB2011-11-26 13:12 2517人阅读 评论(0) 收藏 举报 mysqlsessionjava   1.查看当前会话隔离 ...

  3. MySQL事务隔离级别测试实例

    https://www.cnblogs.com/huanongying/p/7021555.html MySQL事务隔离级别 事务隔离级别 脏读 不可重复读 幻读 读未提交(read-uncommit ...

  4. Mysql事务-隔离级别

    MYSQL事务-隔离级别 事务是什么? 事务简言之就是一组SQL执行要么全部成功,要么全部失败.MYSQL的事务在存储引擎层实现. 事务都有ACID特性: 原子性(Atomicity):一个事务必须被 ...

  5. MySQL事务隔离级别 解决并发问题

    MySQL事务隔离级别 1. 脏读: 骗钱的手段, 两个窗口或线程分别调用数据库转账表,转账后未提交,对方查看到账后,rollback,实际钱没转. 演示方法: mysql默认的事务隔离级别为repe ...

  6. mysql事务隔离级别、脏读、幻读

    Mysql事务隔离级别本身很重要,再加上可能是因为各大公司面试必问的缘故,在博客中出现的概率非常高,但不幸的是,中国的技术博客要么是转载,要么是照抄,质量参差不齐,好多结论都是错的,对于心怀好奇之心想 ...

  7. mysql事务隔离级别与设置

    mysql数据库,当且仅当引擎是InnoDB,才支持事务: 1.隔离级别 事务的隔离级别分为:未提交读(read uncommitted).已提交读(read committed).可重复读(repe ...

  8. MySQL事务隔离级别(二)

    搞清楚MySQL事务隔离级别 首先创建一个表 account.创建表的过程略过(由于 InnoDB 存储引擎支持事务,所以将表的存储引擎设置为 InnoDB).表的结构如下: 为了说明问题,我们打开两 ...

  9. MySQL事务隔离级别(一)

    本文实验的测试环境:Windows 10+cmd+MySQL5.6.36+InnoDB 一.事务的基本要素(ACID) 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做 ...

随机推荐

  1. BZOJ 2648 世界树

    题目传送门 分析: 喜 闻 乐 见 的虚树 但是建好虚树后的DP也非常的恶心 我们先考虑每个关键点的归哪个点管 先DFS一次计算儿子节点归属父亲 再DFS一次计算父亲节点归属儿子 然后然后我们对于虚树 ...

  2. Ogre源码学习-Image和Texture

    以下文字来自源码注释: Image类:保存未压缩的图片数据,是唯一一个可以加载纹理的类.Image对象调用Codec对象来为图片数据解码. 通常,当在图片被加载前需要对它进行额外的处理,或者你想把它复 ...

  3. Qt Installer Framework翻译(7-5)

    操作 这些操作由组件和控制脚本准备,并由安装程序执行. 注意:操作是通过线程执行的. 在内部,每个操作都有一个DO步骤,包含有关安装程序的说明,以及一个UNDO步骤,包含有关卸载程序的说明. 操作总结 ...

  4. Centos搭建PXE,安装部署操作系统

    centos系统搭建PXE网络安装centos+ubuntu+Windows Centos搭建PXE,安装部署操作系统 一 . 原理: 1.什么是PXE: PXE(Pre-boot Execution ...

  5. 简单看看读写锁ReentantReadWriteLock

    前面我们看了可重入锁ReentrantLock,其实这个锁只适用于写多读少的情况,就是多个线程去修改一个数据的时候,适合用这个锁,但是如果多个线程都去读一个数据,还用这个锁的话会降低效率,因为同一时刻 ...

  6. pycharm 固定模板使用者和日期

    如上图修改就可以正常修改模板了修改后每创建一个python文件就会是这种效果

  7. 【译】SQ3R学习法则

    SQ3R 观察-提问-阅读-复述-回顾 背景 SQ3R是一种理解策略,可帮助学生在阅读时思考他们正在阅读的文章. SQ3R通常被归类为学习策略,通过教导学生在初次阅读一篇文章时如何阅读和像高效读者一样 ...

  8. 原生Ajax发送get、post请求每一步

    说明 发送Ajax的请求的核心对象是XMLHttpRequest,因此我们需要了解该对象的相关属性和方法 方法(图一) 属性(图二) 第一步:创建 XMLHttpRequest对象,下面都简写为 xh ...

  9. 理解numpy中ndarray的内存布局和设计哲学

    目录 ndarray是什么 ndarray的设计哲学 ndarray的内存布局 为什么可以这样设计 小结 参考 博客:博客园 | CSDN | blog 本文的主要目的在于理解numpy.ndarra ...

  10. 85道Java微服务面试题整理(助力2020面试)

    微服务 面试题 1.您对微服务有何了解? 2.微服务架构有哪些优势? 3.微服务有哪些特点? 4.设计微服务的最佳实践是什么? 5.微服务架构如何运作? 6.微服务架构的优缺点是什么? 7.单片,SO ...