数据库4—数据库基础·事务管理和并发控制

数据库知识 - 索引目录

一、事务的概念

1、ACID属性

1.1 讲解

数据库事务是指一系列数据库操作,它们组成了一个逻辑工作单元,要么全部成功执行,要么全部失败回滚,以确保数据库的一致性和完整性。

ACID是四个属性的首字母缩写,用于描述事务的特性:

  1. 原子性(Atomicity): 事务是原子的,要么全部执行成功,要么全部回滚失败。如果事务中的任何一步失败,系统会撤销整个事务,回到事务开始前的状态,保持数据库的一致性。

  2. 一致性(Consistency): 事务使数据库从一致的状态转移到另一个一致的状态。这意味着事务执行后,数据库仍然保持一致性约束,不会因为事务执行而破坏完整性。

  3. 隔离性(Isolation): 事务的执行是相互隔离的,即一个事务的执行不应该影响其他事务的执行。这可以通过并发控制来实现,确保多个事务并发执行时,系统能够保持隔离性。

  4. 持久性(Durability): 一旦事务提交,其结果应该是永久性的,即使系统发生故障也不应该丢失。这通常通过将事务的变更持久化到磁盘上的日志中来实现。

1.2 示例及解释

现在,让我们通过一个简单的例子来说明这些概念。

假设我们有一个银行数据库,包含两张表:账户(Accounts)和交易记录(Transactions)。

账户表:

账户ID 余额
1 1000
2 500

交易记录表:

交易ID 账户ID 金额
1 1 -200
2 2 +200

现在,让我们考虑一个事务,将账户1的余额减少200,同时将账户2的余额增加200。这个事务要满足ACID属性。

  1. 原子性: 这个事务要么成功,要么失败。如果在进行途中发生故障,例如数据库崩溃,系统会回滚事务,确保不会只有一部分操作被执行。

  2. 一致性: 在事务执行之前和之后,数据库必须保持一致性。在这个例子中,一致性意味着总余额不变,即账户1减少200,账户2增加200。

  3. 隔离性: 如果有其他事务在同一时间修改账户余额,系统必须确保这两个事务相互隔离,不会相互干扰。这通常通过锁或其他并发控制机制来实现。

  4. 持久性: 一旦事务提交,数据库应该持久保存变更。如果事务提交后数据库崩溃,系统应该能够通过事务日志等手段,将数据库还原到提交事务后的状态。

2、事务的状态和特性

2.1 事务的状态

事务可以处于以下几种状态:

  1. 活动(Active): 事务处于活动状态,表示事务已经开始执行,但尚未提交或回滚。

  2. 部分提交(Partially Committed): 事务已经执行完所有操作,并且已经发送了提交请求,但还未得到最终确认。在这个状态下,数据库正在将事务的结果写入磁盘,但还未完成。

  3. 失败(Failed): 事务执行过程中发生了错误,导致无法继续执行。这时候系统会回滚事务,将数据库恢复到事务开始前的状态。

  4. 提交(Committed): 事务已经成功执行,并且已经得到了最终确认,所有的操作已经被永久保存到数据库中。

  5. 回滚(Aborted/Rolled Back): 事务执行失败或者被取消,数据库将回滚事务,撤销所有的操作,将数据库恢复到事务开始前的状态。

2.2 事务的特性

事务具有以下几个重要的特性:

  1. 原子性(Atomicity): 事务是原子的,要么全部执行成功,要么全部失败回滚。这意味着事务中的所有操作要么全部执行,要么全部不执行,不会出现部分执行的情况。

  2. 一致性(Consistency): 事务执行后,数据库从一个一致的状态转移到另一个一致的状态。这意味着事务执行不会破坏数据库的完整性约束。

  3. 隔离性(Isolation): 多个事务并发执行时,系统必须保证它们相互隔离,互不干扰。这可以通过并发控制机制来实现,以防止数据不一致或者丢失。

  4. 持久性(Durability): 一旦事务提交,其结果应该是永久性的,即使系统发生故障也不应该丢失。数据库系统通常通过事务日志等手段来实现持久性。

2.3 示例

让我们通过一个简单的示例来说明事务的状态和特性。

假设我们有一个银行数据库,包含账户表和交易记录表。现在,我们要执行一个转账的事务,将100元从账户A转到账户B。

  1. 事务状态: 在开始执行转账事务时,事务处于活动状态。如果转账成功并提交,事务将进入提交状态;如果转账失败并回滚,事务将进入回滚状态。

  2. 事务特性: 转账事务必须满足原子性,要么账户A减少100元,账户B增加100元,要么两者都不发生变化;一致性,转账后账户总金额不变;隔离性,转账事务执行时不应受到其他并发事务的影响;持久性,一旦转账成功提交,账户余额变化应该是永久性的。

二、并发控制

1、并发问题和并发控制的重要性

数据库并发控制是为了解决多个用户同时访问数据库时可能出现的数据不一致和并发冲突的问题。

1.1 并发问题

在数据库中,当多个用户同时对同一数据进行读取或修改时,可能会出现以下并发问题:

  1. 丢失更新(Lost Update): 当两个事务同时读取同一数据并尝试更新它时,后提交的事务可能会覆盖先提交的事务所做的修改,导致数据的更新丢失。

  2. 脏读(Dirty Read): 一个事务读取了另一个事务尚未提交的数据,如果另一个事务在后续回滚,读取的数据就是无效的,这就是脏读。

  3. 不可重复读(Non-Repeatable Read): 一个事务在读取某个数据后,另一个事务修改了该数据并提交,导致第一个事务再次读取同一数据时得到了不同的结果。

  4. 幻读(Phantom Read): 一个事务在读取一系列数据后,另一个事务插入了新的数据,导致第一个事务再次读取同一系列数据时发现了新增的“幻影”数据。

1.2 并发控制的重要性

并发控制的重要性在于确保数据库操作的正确性和一致性,以及避免上述并发问题的发生。通过合适的并发控制机制,可以保证多个并发事务之间的隔离性,避免数据不一致和冲突的发生。

1.3 示例

让我们通过一个简单的示例来说明并发问题和并发控制的重要性。

假设有一个银行数据库,包含账户表和交易记录表。现在,有两个用户同时尝试从同一个账户中取款,并且账户余额为1000元。

  • 用户A尝试取款500元,用户B尝试取款600元。
  • 如果没有并发控制,可能会出现丢失更新的问题,即用户B的取款操作覆盖了用户A的取款操作,导致账户余额不正确。

通过合适的并发控制机制,例如锁机制或多版本并发控制(MVCC),可以确保在并发情况下,每个用户的取款操作都能正确地读取和更新账户余额,避免出现丢失更新、脏读、不可重复读或幻读等问题。

2、锁定机制和事务隔离级别

2.1 锁定机制

数据库锁定机制是一种控制并发访问的手段,通过在数据上设置锁,限制对该数据的并发访问,以确保事务的隔离性。

有两种主要类型的锁定:

  1. 共享锁(Shared Lock): 多个事务可以同时持有共享锁,允许它们同时读取共享数据,但不允许写入。共享锁用于读取操作,不阻止其他事务持有相同的共享锁。

  2. 排他锁(Exclusive Lock): 一个事务持有排他锁时,其他事务不能同时持有任何锁,包括共享锁和排他锁。排他锁用于写入操作,确保在写入时不会有其他事务读取或写入相同的数据。

2.2 事务隔离级别

事务隔离级别定义了在并发环境下,一个事务对数据库的修改对其他事务的可见性程度。

有四个标准的事务隔离级别,按照严格程度递增:

  1. 读未提交(Read Uncommitted): 允许一个事务读取另一个事务未提交的数据,是最低的隔离级别,但也是最灵活的。

  2. 读已提交(Read Committed): 一个事务只能读取已提交的数据,避免了脏读,但可能会出现不可重复读和幻读。

  3. 可重复读(Repeatable Read): 事务在整个过程中可以多次读取相同的数据,确保了在事务执行期间其他事务对数据的修改不可见。可以防止脏读和不可重复读,但仍可能发生幻读。

  4. 串行化(Serializable): 最高的隔离级别,确保了事务的完全隔离,防止了所有并发问题,但可能会导致性能下降。

2.3 示例

让我们通过一个简单的示例来说明锁定机制和事务隔离级别。

一个图书库存管理系统,有一张图书表:

图书表:

图书ID 图书名称 库存量
1 数据库原理 50
2 Java编程入门 30

现在有两个事务:

  1. 事务A: 从图书库存中读取图书ID为1的图书,并将库存量减少10。
  2. 事务B: 从图书库存中读取图书ID为1的图书,并将库存量减少20。
  • 锁定机制: 事务A在读取和修改图书信息时,可能会使用排他锁,防止其他事务同时读取或修改相同的图书信息。
  • 事务隔离级别: 如果事务A和事务B都在读未提交的隔离级别下运行,可能会导致事务B读取到了事务A未提交的修改。在可重复读或串行化的隔离级别下,可以避免这种情况。

猜你喜欢

转载自blog.csdn.net/weixin_49015143/article/details/134946299
今日推荐