教你事务管理理论知识乐字节

26次阅读

共计 1814 个字符,预计需要花费 5 分钟才能阅读完成。

事务管理理论知识

事务概念

事务就是对数据库的一次操作,要么全副胜利,要么全副失败。事务是最小的逻辑执行单元,也是数据库并发管制的根本单位。其作用就是确保数据的准确性。

事务四大个性

原子性 (Atomicity)

原子性是指事务蕴含的所有操作要么全副胜利,要么全副失败回滚。保障事务内的操作是不可分割的。

一致性 (Consistency)

一致性是指事务执行的后果必须使数据库从一种一致性状态变到另一种一致性状态。比方转账,假如用户 A 和用户 B 两者的钱加起来一共是 2000,那么不论 A 和 B 之间如何转账,转几次账,事务完结后两个用户的钱相加起来应该还得是 2000,不可能呈现其余状况。

隔离性 (Isolation)

隔离性是指并发执行的事务之间不能相互影响。比方写一条 update 语句和 delete 语句,而且同时操作一条记录,如果不加管制那就会呈现各种问题。

持久性 (Durability)

持久性是指一个事务一旦被提交了,那么对数据库中的数据的扭转就是永久性的,即使是在数据库系统遇到故障的状况下也不会失落提交事务的操作。比方执行 insert 语句后,就必须要有数据写入磁盘。

总之,这四个个性是事务管理的基石,其中,原子性是根底,隔离性是伎俩,持久性是目标,真正的老大就是一致性。其中最难的是隔离性,因为事务是原子操作,但事务与事务之间能够并发执行,因而要达到一致性就要求事务与事务之间进行隔离,那么事务如果不隔离间接并发执行会造成什么结果呢?

事务并发问题

脏读

脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。

工夫 事务 A(贷款) 事务 B(取款)
T1 开始事务
T2 开始事务
T3 查问余额(500 元)
T4 取出 500 元(余额 0 元)
T5 查问余额(0 元)
T6 撤销事务(余额复原为 500 元)
T7 存入 100 元(余额 100 元)
T8 提交事务

余额应该为 600 元才对!请看 T5 工夫点,事务 A 此时查问余额为 0 元,这个数据就是脏数据,它是事务 B 造成的,显著事务没有进行隔离,渗过来了,乱套了。

不可反复读

不可反复读是指在对于数据库中的某个数据,一个事务范畴内屡次查问却返回了不同的数据后果,这是因为在查问距离,被另一个事务批改并提交了。

工夫 事务 A(贷款) 事务 B(取款)
T1 开始事务
T2 开始事务
T3 查问余额(500 元)
T4 查问余额(500 元)
T5 取出 500 元(余额 0 元)
T6 提交事务
T7 查问余额(0 元)

事务 A 其实除了查问了两次以外,其余什么事件都没有做,后果钱就从 1000 变成 0 了,这就是反复读了。可想而知,这是他人干的,不是我干的。其实这样也是正当的,毕竟事务 B 提交了事务,数据库将后果进行了长久化,所以事务 A 再次读取天然就产生了变动。这种景象也失常,但在某些场景下的确不容许的(比方电商中扣减库存)。

虚读 (幻读)

幻读是事务非独立执行时产生的一种景象,即在一个事务读的过程中,另外一个事务可能插入了新数据记录,影响了该事务读的后果。

工夫 事务 A(统计总贷款) 事务 B(贷款)
T1 开始事务
T2 开始事务
T3 统计总贷款(1000 元)
T4 存入 100 元
T5 提交事务
T6 统计总贷款(1100 元)

演绎一下,以上提到了事务并发所引起的跟读取数据无关的问题,各用一句话来形容一下:

  1. 脏读:事务 A 读取了事务 B 未提交的数据,并在这个根底上又做了其余操作。
  2. 不可反复读:事务 A 读取了事务 B 已提交的更改数据。
  3. 幻读:事务 A 读取了事务 B 已提交的新增数据。

第一条是坚定抵制的,后两条在大多数状况下可不作思考。正因为事务并发时会呈现问题,因而数据库专家们就提出了解决方案即事务的隔离级别。

事务隔离级别

不同数据库的事务隔离级别不尽相同 。MySQL 数据库反对上面的四种隔离级别,并且 5.5 当前默认为 Repeatable read 级别,之前是 Read committed;而在 Oracle 数据库中,只反对 Serializable 级别和 Read committed 这两种级别,并且默认为 Read committed 级别。MySQL 数据库为咱们提供了四种隔离级别,别离为:

事务隔离级别 脏读 不可反复读 幻读
READ_UNCOMMITTED 容许 容许 容许
READ_COMMITTED 禁止 容许 容许
REPEATABLE_READ 禁止 禁止 容许
SERIALIZABLE 禁止 禁止 禁止

# 查问隔离级别
select @@tx_isolation; 

# 设置隔离级别
set [glogal | session] transaction isolation level 隔离级别名称;

正文完
 0