更新和插入的并发问题_MySQL事务处理与并发控制

本文详细介绍了数据库事务处理的重要性、ACID特性、并发控制的必要性以及MySQL中的事务处理和并发控制技术。内容涵盖事务的四大特性、并发控制的挑战、MySQL事务模型、InnoDB的日志技术(redo log、undo log和doublewrite buffer)以及并发控制机制(锁和MVCC)。此外,还深入探讨了不同隔离级别的数据异常,以及如何在可重复读隔离级别下解决写偏序问题。
摘要由CSDN通过智能技术生成

概述

文章有点长哟,需要耐心看哟

数据库系统是现代商业世界有序稳定运行的基石,数据和数据承载的交易事件的结果不会因系统故障而损伤。数据库系统的核心技术是事务处理机制,也是有别于其他系统的关键特质。事务处理机制以其ACID特性保证了在各种环境下的数据一致性。同时:数据库系统又是多用户处理系统,为了提高数据库的性能,数据库常常会并发执行多个事务,事务的并发执行,虽然提高了性能,但是却带来了其他的数据一致性问题,因此,合适的并发控制技术是必须的,本文主要介绍MySQL的事务处理和并发控制技术。

1. 数据库事务系统概述

数据库管理系统是位于用户与操作系统之间的一层数据管理软件,数据库的事务处理机制是数据库的基石,那么为什么需要事务处理机制呢?

1.1 为什么需要事务处理机制

我们先看一个问题:账户A转账50元到账户B,过程如下:

03e949c7fe370b5a202509a610942fe8.png

账户转账示例

事务处理机制就是要通过实现事务的ACID特性来保证用户对数据的操作是安全的一致的,不管在什么环境下,都必须是安全的一致的。事务概念为应用程序开发人员提供了一个非常好的抽象,同时保证了数据的安全一致性。

1.2 什么是事务呢?具有哪些特性

前面我们通过例子简单的认识了事务处理的必要性,那么事务到底是什么呢?它的ACID特性该如何理解呢?

事务是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成,事务是无法被分割的操作,事务必须作为一个完整的单元成功或失败,不可能存在部分完成的事务。

事务具有如下特性:

原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束。隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行。持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中。

那么该如何理解这四个特性呢?

  • 1.原子性:ACID的原子性描述了当客户想进行多次写入,但在一些写操作处理完之后出现故障的情况。例如进程崩溃,网络连接中断,磁盘变满或者某种完整性约束被违反。如果这些写操作被分组到一个原子事务中,并且该事务由于错误而不能完成(提交),则该事务将被中止,并且数据库必须丢弃或撤消该事务中迄今为止所做的任何写入。如果没有原子性,在多处更改进行到一半时发生错误,很难知道哪些更改已经生效,哪些没有生效。该应用程序可以再试一次,但冒着进行两次相同变更的风险,可能会导致数据重复或错误的数据。原子性简化了这个问题:如果事务被中止(abort),应用程序可以确定它没有改变任何东西,所以可以安全地重试。ACID原子性的定义特征是:能够在错误时中止事务,丢弃该事务进行的所有写入变更的能力。即:可中止的。
  • 2.一致性:ACID一致性的概念是,对数据的一组特定陈述必须始终成立。例如我们之前举例的转账。一致性更多的强调的是数据库状态的变迁,即:数据库必须从一个有序状态变迁到另一个有序状态,那么什么是有序的? 答案是:数据在事务的操作下,始终符合用户定义的所有完整性约束可见:原子性,隔离性和持久性是数据库的属性,而一致性(在ACID意义上)是应用程序的属性。应用可能依赖数据库的原子性、隔离性和持久性来实现数据额一致性
  • 3.隔离性:大多数数据库都会同时被多个客户端访问。如果它们各自读写数据库的不同部分,这是没有问题的,但是如果它们访问相同的数据库记录,则可能会遇到并发问题(竞争条件(race conditions))。如下图显然违背了隔离性:
a4aa374a43c20999d84729375d762922.png

ACID意义上的隔离性意味着,同时执行的事务是相互隔离的:它们不能相互冒犯。传统的数据库教科书将隔离性形式化为可串行化(Serializability),这意味着每个事务可以假装它是唯一在整个数据库上运行的事务。数据库确保当事务已经提交时,结果与它们按顺序运行(一个接一个)是一样的,尽管实际上它们可能是并发运行的。不过在实际生产环境中,很少使用可串行化,因为这会使得性能大幅降低。

4.持久性:数据库系统的目的是,提供一个安全的地方存储数据,而不用担心丢失。持久性 是一个承诺,即一旦事务成功完成,即使发生硬件故障或数据库崩溃,写入的任何数据也不会丢失。当然了,没有绝对的持久性,如果你的数据所在的磁盘损坏了呢?备份也损坏了呢?因此没有绝对的持久性安全性,增加副本只能增加安全性的几率,但是绝对达不到100%。

以上介绍了数据库的四大特性,接下来看看为什么需要并发控制呢?

1.3 为什么需要并发控制

我们已经知道,数据库会同时被多个用户(多个事务)访问,如果多个事务访问不同的数据,那么事务之间不会有任何干扰,如果多个事务操作相同的数据,那么各个事务之前就会互相干扰违背事务的隔离性,导致数据不一致。因此,为了满足隔离性,使得各个并发的事务互不干扰,数据库系统必须对并发的事务进行控制,即:并发控制。

那么不进行并发控制会有哪些问题呢?

事务之间的关系有如下三种:

  • 1、读--读:如果多个事务都是只读操作,那么这些事务可以并发,不会互相干扰(因为没有数据更新)。
  • 2、读--写:如果读写都存在,则会存在脏读、不可重复度、幻读等问题。
  • 3、写--写:如果多个事务并发的写同一数据,如果不加并发控制也会带来数据异常。

接下来看看三种常见的读异常:

876bd50f794d81b0426468a8afd30bce.png

读数据异常

如上图:脏读:如果没有并发控制机制,事务T2在Time1处读到了无效的数据(因为事务T1在Time2时中止了)不可重复读:事务T1在Time3处发生了不可重复读(同一个事务,在事务执行的过程中,同一行数据,读到了不同的值)幻读:事务T1在Time3处发生了幻读。

没有并发控制的情况下,读--写操作不仅会造成三种读异常,写写操作也会造成写异常,下边我们看看写-写操作导致的异常:

fe8e7867c73182bae42fa28381a7bab2.png

写数据异常

如上图: 脏写:事务T1在time3时刻回滚掉了不是自己修改的数据,即事务T1在time3出发生了脏写。丢失更新:事务T1在time3处覆盖掉了不是自己修改的数据,即T1在time3出发生了丢失更新异常,如果是T2在time3时提交,道理也是一样的,只不过在T2上发生了丢失更新。

除了以上读写异常,还存在一种**语义约束(事务的特性是要保证语义约束的)**引发的数据异常--写偏序:为了理解写偏序,我们先看一个例子(该例子来自《数据密集型应用系统设计》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值