略谈事务ACID

数据库事务

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

简言之:

要么都成功,要么都失败。

ACID

数据库事务正确执行的四个基本原则的缩写;

包含:

原子性(Atomicity)一致性(Consistency)隔离性(Isolation)持久性(Durability)

一个支持事务的数据库(例如:INNODB引擎),必须要具有这四种特性。

以经典的银行转账为例略谈一下

原子性

事务中的全部操作在数据库中是不可分割的,要么全部完成,要么全部不执行。

例:A用户给B用户转账500元

银行执行结果
A用户(1000元)1000-500500
B用户(500元)500+5001000

在转账过程中,这两个步骤只能成功或失败,不得出现一个用户资金有变动而另一个用户资金没变动的情况。

一致性

几个并行执行的事务,其执行结果必须与按某一顺序串行执行的结果相一致。

银行执行结果
A用户(1000元)1000-500500
B用户(500元)500+5001000
总计(1500元)15001500

在整个操作过程中,其两个用户的资金总额是恒定不变的。

隔离性

事务的执行不受其他事务的干扰,事务执行的中间结果对其他事务必须是透明的。

例:A用户给B用户转账500元,C用户给B用户转账500元

银行执行结果
A用户(1000元)1000-500500
B用户(500元)500+5001000
银行执行结果
C用户(1000元)1000-500500
B用户(500元)500+5001000
银行最终结果
A用户500
B用户1500
C用户500

在多用户进行操作的时候,主要是排除其他用户对自身的一个影响。

持久性

对于任意已提交事务,系统必须保证该事务对数据库的改变不被丢失。

如在提交一组事务的时候遇到服务器崩溃或者断电,若事务未完成提交,则恢复到原来的状态;若事务已完成提交,则持久化到数据库中;

事务一旦提交,便不可逆。

事务并发问题

数据库是要被广大客户所共享访问的,那么在数据库操作过程中不考虑隔离问题的话很可能诱发一些非常情况。

脏读

一个事务读取到了另一个事务未提交的数据操作结果。

在A给B完成转账的时候,B是1000元,但是在C给B转账的时候,读取到的是A未给B转账前的数据(500元),结果造成了两边数据不对等情况;

这种情况相当危险,因为很可能所有的操作都被回滚。

不可重复读

一个事务对同一行数据重复读取多次,但是却得到结果不同。

第一次读取值:

用户资金
A1000
B500

第二次读取值:A用户有入账情况

用户资金
A2000
B500

第三次读取值:B用户有支出情况

用户资金
A2000
B200

不可重复读不一定是错误,也可能是读取时间的问题所导致;

虚读(幻读)

一个事务内读取到了别的事务插入的数据,导致前后读取不一致。

第一次读取值:

用户资金
A1000
B500

第二次读取值:多了一条记录

用户资金
A1000
B500
D1000

虚读一般无较大影响,一般为行影响。

事务隔离级别

在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别;在标准SQL规范中,定义了四种事务隔离级别:

读未提交(READ UNCOMMITTED)读提交 (READ COMMITTED)

可重复读 (REPEATABLE READ)串行化 (SERIALIZABLE)

不同的隔离级别对事务的处理不同,从上往下,隔离强度逐渐增强,性能逐渐变差,其中,可重复读是 MySQL 的默认隔离级别。

隔离级别脏读不可重复读虚读(幻读)
读未提交
读提交×
可重复读××
串行化×××

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿鹏同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值