数据库事务的四大特性以及事务的隔离级别整理

CeShiYuan
• 阅读 387

事务的四大特性

  • 原子性(atomicity)

我们经常说,一个事务执行失败了,就得回滚,其实这就是事务的原子性,一个完整事务,要么全部执行成功,如果有一个或者多个失败,那么就要回滚,其实这也是另一个特性即一致性的基础

  • 一致性(consistency)

一致性,先举个栗子,最容易理解的栗子,本来刘备有200元,关羽没有钱,那么刘备给关羽转账100元,现在需要两步执行这个操作,先减去刘备账户里面的100元,第二步,给关羽账号增加100元,那么这两步算是一个事务。在事务发生前,关羽0 +刘备200=200元,事务结束后,关羽100+刘备100=200,数据没有平白增加或者减少。而且不管这兄弟俩怎么转,这个总和不会发生变化,这就是事务的一致性。一致性就是说事务必须使用数据库从一个一致性状态变换到另一个一致性状态。想想我们讲的第一个原子性,如果一半成功,一半失败而没有回滚,还会有数据的一致性吗?

  • 隔离性(isolation)

隔离性主要是针对并发访问来讲的,当多个用户修改数据表时,数据库为每一个用户开启的事务,不能被其他的事务干扰,多个并发要互相隔离,即对于同一个资源,在同一个时间段只能有一个事务可以修改

  • 持久性(durability)

持久性就是说一旦事务成功提交,那么对于数据库来说,这种改变是持久的

事务的隔离级别

在mysql中,支持四种隔离级别,即ru,rc,rr,serializealbe,后面我们会一一讲解,mysql默认支持的的rr,

  • 此处给大家推荐一款好用的数据库管理工具,jetbrains出品的datagrip;好用哇哇!,下面的sql语句都是在datagrip中运行的

数据库事务的四大特性以及事务的隔离级别整理

  • READ UNCOMMITTED(未提交读)
  • ru是指在一个事务执行未完成的时候,数据对其他事务也是可见的,而且读取的是已经更改但是还没有commit的数据,这种保证不了数据准确的隔离级别几乎是不用的。也正如此,所以它的性能是最优的

    • 创建相关的数据库和数据表
create schema test;
use test;
CREATE TABLE `t` (
                     `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
                     `point` int(11) DEFAULT NULL,
                     PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
  • 下面粘贴sql语句,注意在同一行的代码先左后右执行,是在两个sql窗口执行的,在执行到第6行的时候发现,console2开启了事务,但是还没有commit,但是console1已经查询到未提交的结果了。这就是读未提交

数据库事务的四大特性以及事务的隔离级别整理

  • READ COMMITTED(读已提交)

大部分的数据库默认隔离级别就是rc,就是说一个事务只能看见已经提交的修改结果,如果没有提交,那么只能看见原来的结果,而不会看到修改未提交的结果,但是这会出现一个问题,什么问题呢?就是 在一个事务中,如果另一个事务修改了数据并且提交,那么在第一个事务中针对同一个查询,就会查询出来两个不同的数据,即不可重复读
数据库事务的四大特性以及事务的隔离级别整理

  • 新增一条如果没有提交也是读取不到的

数据库事务的四大特性以及事务的隔离级别整理

  • 这个时候,如果两个窗口同时对一条数据更改会发生什么情况呢?第二条更新命令会一直等第一条命令的提交,未提交就处于等待状态

数据库事务的四大特性以及事务的隔离级别整理

  • REPEATABLE READ(可重复读)
    可重复读是mysql默认的隔离级别,rr解决了脏读的问题,但是可能会出现幻读,下面先来演示一下幻读的实现

    • 看一下已经解决了读未提交的问题和不可重复读的问题

数据库事务的四大特性以及事务的隔离级别整理

  • 幻读其实是解决不可重复读的一个缺点,为什么?首先事务1已经执行了一个插入操作,新增id3,但是为了可重复读,事务2看不到新增的数据,所以当事务2增加id3的时候报错,因为id3在数据表中已经切切实实的存在了。可重复读,有点像把某一个时刻的数据作为快照写入了缓存,在commit之前所有的读取都是源自缓存,而非真实的表

数据库事务的四大特性以及事务的隔离级别整理

SERIALIZABLE(可串行化)

其实我们可以先自己想一下,如何在解决重复读的时候还能解决幻读呢?是不是感觉有点不可能,既然不幻读,那就实现不了可重复读,然鹅,但是,前面的操作都是基于两个事务,但是如我们把两个事务再关联一下呢,是不是就可以解决了,这就是串行的意思,可串行化解决了脏读,幻读,可重复读等问题,但是,势必会影响效率,"可串行化"会在读取的每一行数据上都加锁,所以可能会导致大量的锁等待和超时问题,所以在实际的生产环境中也很少会用到这个隔离级别,只有在非常需要确保数据的一致性切可以接受没有并发的情况下,才会考虑使用这个隔离级别。

  • 演示一下,先看一下目前的情况

数据库事务的四大特性以及事务的隔离级别整理

  • 怎么实现串行化呢,说起来有点恶心,这次不是缓存快照了,让你读实时数据,但是更新操作我给你停了。我让你等到没有事务了,或者其他事务都提交了,才让你这个写操作执行,嗯,就是这样。感觉有点不太高明

数据库事务的四大特性以及事务的隔离级别整理

  • 用了锁,有人读也上锁,有人写也上锁,效率能没有影响吗,写之前先看有没有读锁,有读锁就等待。这种方式就是 简单,粗暴

数据库事务的四大特性以及事务的隔离级别整理

  • 综合下来,还是看使用的业务场景选择不同的隔离级别,个人感觉大部分业务还是用rc比较好。你觉得呢?

附sql脚本
console1.sql

use test;
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
#READ UNCOMMITTED(未提交读)
start transaction ;
select * from t where id =1;
update t set point=50 where id =1;
commit ;
#READ COMMITTED(读已提交)
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
select * from t where id =1;
start transaction ;
update t set point=80 where id =1;
insert into t values (null,200);
select * from t where id =2;
commit ;

#REPEATABLE READ(可重复读)
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ ;
select * from t ;
start transaction ;
update t set point=100 where id=1;
commit ;

start transaction ;
select * from t ;
insert into t values (null,300);
select * from t ;
commit


## SERIALIZABLE(可串行化)
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE ;
start transaction ;
select * from t;
insert into t values (null,123);

console2.sql

use test;
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
#READ UNCOMMITTED(未提交读)
start transaction ;
select * from t where id =1;
select * from t where id =1;
commit ;
#READ COMMITTED(读已提交)
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
select * from t where id =1;
start transaction ;
update t set point=10 where id =1;
select * from t where id =1;
select * from t where id =2;
commit ;

#REPEATABLE READ(可重复读)
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ ;
select * from t ;
start transaction ;
select * from t where id=1;
select * from t where id=1;

start transaction ;
select * from t ;
select * from t ;
insert into t values (3,300);
commit


## SERIALIZABLE(可串行化)
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE ;
start transaction ;
select * from t;
commit;


本篇文章由一文多发平台ArtiPub自动发布

点赞
收藏
评论区
推荐文章
Easter79 Easter79
3年前
TiDB 性能竞赛 11.16
TiDB实现了快照隔离级别的分布式事务,支持悲观锁、乐观锁,同时也解决了大事务的难点。事务是数据库的基础,提供高效的、支持完整ACID的分布式事务更是分布式数据库的立足之本。事务是数据库执行的最小单元,允许用户将多个读写操作组合为一个逻辑单元。事务需要满足原子性、一致性、隔离性和持久性,也就是ACID。数据库有多种并发控制方法,乐观并发控制(
Easter79 Easter79
3年前
Spring事务(二):Spring事务的特点
事务特性实现事务必须满足以下四大特性:Atomicity(原子性):构成事务的的所有操作必须是一个逻辑单元,要么全部执行,要么全部不执行。Consistency(一致性):数据库在事务执行前后,完整性没有被破坏。(转账前后,钱的总数不变)Durability(持久性):事务执行成功后必须全部写入磁盘。
Wesley13 Wesley13
3年前
mysql 事物四大特性和事物的四个隔离
1、事物四大特性(ACID)1.原子性(atomicity):一个事务必须视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能只执行其中的一部分操作,这就是事务的原子性。2.一致性(consistency):数据库总数从一个一致性的状态转换到另一个一致性的状态。3.隔离性
Wesley13 Wesley13
3年前
MySQL InnoDB如何保证事务特性
如果有人问你“数据库事务有哪些特性”?你可能会很快回答出原子性、一致性、隔离性、持久性即ACID特性。那么你知道InnoDB如何保证这些事务特性的吗?如果知道的话这篇文章就可以直接跳过不看啦(^.^)先说结论:redolog重做日志用来保证事务的持久性undolog回滚日志保证事务的原子性undologredo
Wesley13 Wesley13
3年前
MySql学习17
一.数据库事务的四大特性(ACID)如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性:原子性(Atomicity):原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,这和前面两篇博客介绍事务的功能是一样的概念,因此事务的操作如果成功就必须要完全应用到数据库,如果操
Wesley13 Wesley13
3年前
MySQL transaction
MySQLtransaction(数据库的事务)数据库事务(DatabaseTransaction),是指作为单个逻辑工作单元执行的一系列操作。要么完全执行,要么完全地不执行。ACID事务必须具备ACID四个特性原子性(Atomicity)原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚。一致性(Consistency)
Wesley13 Wesley13
3年前
MySQL知识体系——事务
ACID(事务的四大特性)    四个特性中,最重要的就是一致性。由原子性,隔离性,持久性来保证。(以下描述用例:用户A、B、C分别在银行拥有500元存款)    原子性(Atomicity)        事务是一个不可分割的工作单元,事务中的操作要么全部COMMI
Wesley13 Wesley13
3年前
MySQL 事务的四大特性ACID介绍
事务的四大特性(ACID)1、原子性(Atomicity)事务是一个不可分割的单位,事务中的所有SQL等操作要么都发生,要么都不发生。2、一致性(Consistency)事务发生前和发生后,数据的完整性必须保持一致。3、隔离性(Isolation)当并发访问数据库时,一个正在执行的事务在执行完毕前,对应其他的会话是不可见的,多个并发事
Wesley13 Wesley13
3年前
MySQL常见问题
事务四大特性原子性:不可分割的操作单元,事务中所有操作,要么全部成功;要么撤回到执行事务之前的状态一致性:如果在执行事务之前数据库是一致的,那么在执行事务之后数据库也还是一致的;隔离性:事务操作之间彼此独立和透明互不影响。事务独立运行。这通常使用锁来实现。一个事务处理后的结果,影响了其他事务,那么其他事务会撤回。
事务的ACID,隔离级别,脏读,幻读和不可重复读
事务的ACID原子性(atomicity)一个事务中执行的sql语句,要么全部成功,要么全部失败,不可能一部分成功。一致性(consistency)事务执行前和执行后数据一致,也就是说事务中的sql语句不能只执行一部分。这种请款一般发生在事务异常中断,服