搞懂什么是数据库事务

时间:2021-05-24 10:21:59   收藏:0   阅读:0

前言

事务(Transaction)是数据库学习中非常重要的一种概念,作为关系型数据库的核心组成,在数据安全方面有着非常重要的作用。

事务在各大数据库中都有非常广泛的应用,并且对于很多业务,例如电商、支付,是保证其可以正常运行的根基

本文会逐步解析数据库事务的核心特性,以获得对事务更深的理解,主要以MySql的InnoDB引擎来讲解。

希望对各位有所帮助,觉得不错可以给点个哦~

事务的定义

事务是一个数据库操作序列,由事务开始事务结束之间执行的全部数据库操作组成,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。

白话讲就是,要么做完,要么别做,做一半了别想跑,你得给把烂摊子收好再走人!

事务中的四大特性:ACID

小案例

什么是ACID,即:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)

来看一个银行转账的案例简单体会一下,然后我们再来详细解释

小明用网银给小红转账100元,在这种交易的过程中,有几个问题需要思考

ACID

原子性

一个事务中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。

事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

一致性

事务的一致性指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态。

如果事务成功地完成,那么系统中所有变化将正确地应用,系统处于有效状态。

如果在事务中出现错误,那么系统中的所有变化将自动地回滚,系统返回到原始状态。

一致性依赖于原子性和隔离性。

隔离性

指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。

由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。

事务查看数据更新时,数据所处的状态要么是另一事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看到中间状态的数据。

持久性

指的是只要事务成功结束,它对数据库所做的更新就必须永久保存下来。

即使发生系统崩溃,重新启动数据库系统后,数据库还能恢复到事务成功结束时的状态。

回到案例

ACID根本问题,是针对不同的事务同时对同一份数据进行写操作的。

实现原理

InnoDB是MySql中唯一支持事务的存储引擎,那么它是如何实现ACID的呢?

主要通过两门技术:并发控制技术日志恢复技术

并发控制技术保证了事务的隔离性,使数据库的一致性不会因为并发执行的操作被破坏。

日志恢复技术保证了事务的原子性,使一致性持久性不会因事务或系统故障被破坏。

技术图片

并发控制

主要就是上锁,流程如下:

日志恢复

事务的隔离级别

前面提到了,数据库的隔离性是依靠并发控制来实现的,也就是通过加锁来实现的。

数据库是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力。

所以对于加锁的处理,就成了数据库的重中之重。

一次封锁锁/两段锁

一次封锁法,就是在方法的开始阶段,已经预先知道会用到哪些数据,然后全部锁住,在方法运行之后,再全部解锁。

这种方式是最为熟知和常用的方法,可以有效的避免循环死锁。

一次封锁法在数据库中并不好用,因为在事务开始阶段,数据库并不知道会用到哪些数据。

数据库采用的是两段锁,将事务分成两个阶段:

事务 加锁/解锁处理
begin;
insert into test ….. 加insert对应的锁
update test set… 加update对应的锁
delete from test …. 加delete对应的锁
commit; 事务提交时,同时释放insert、update、delete对应的锁

两段锁无法避免死锁,但是两段锁协议可以保证事务的并发调度是串行化,关于穿行化后面会进行解释。

四种隔离级别

隐式事务,即单条语句。

前置概念

了解隔离级别之前,我们需要先了解三个概念,脏读、幻读、不可重复读。

脏读

所谓脏读是指一个事务中访问到了另外一个事务未提交的数据,如图:

技术图片

不可重复读

一个事务读取同一条记录2次,得到的结果不一致,如图:

技术图片

幻读

一个事务读取2次,得到的记录条数不一致,如图:

技术图片

隔离级别

在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别。

我们的数据库锁,也是为了构建这些隔离级别存在的。

隔离级别 脏读(Dirty Read) 不可重复读(NonRepeatable Read) 幻读(Phantom Read)
未提交读(Read uncommitted) ? ? ?
已提交读(Read committed) ? ? ?
可重复读(Repeatable read) ? ? ?
可串行化(Serializable ) ? ? ?

可重复读是InnoDB默认级别

总结

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!