数据库并发的五个问题以及四级封锁协议与事务隔离的四个级别

简介: 数据库并发的五个问题以及四级封锁协议与事务隔离的四个级别

五类并发问题

 


丢失更新(第一类丢失更新)

撤销一个事务时,把其他事务已提交的更新数据覆盖(A 和 B 事务并发执行,A 事务执行更新后,提交;B 事务在 A 事务更新后,B 事务结束前也做了对该行数据的更新操作,然后回滚,则两次更新操作都丢失了)。这种并发问题是由于完全没有隔离事务造成的。只要设置隔离级别,数据库就能保证此类问题不发生。

客户损失 100 元。


脏读

一个事务读到另一个事务未提交的更新数据(A 和 B 事务并发执行,B 事务执行更新后,A 事务查询 B 事务没有提交的数据,B 事务回滚,则 A 事务得到的数据不是数据库中的真实数据。也就是脏数据,即和数据库中不一致的数据)。

客户损失 100 元。


不可重复读

一个事务读到另一个事务已提交的更新数据(A 和 B 事务并发执行,A 事务查询数据,然后 B 事务更新该数据,A 再次查询该数据时,发现该数据变化了)。


覆盖更新(第二类丢失更新)

这是不可重复读中的特例,一个事务覆盖另一个事务已提交的更新数据(即 A 事务更新数据,然后 B 事务更新该数据,A 事务查询发现自己更新的数据变了)。

银行损失 100 元。


虚读(幻读)

一个事务读到另一个事务已提交的新插入的数据(A 和 B 事务并发执行,A 事务查询数据,B 事务插入或者删除数据,A 事务再次查询发现结果集中有以前没有的数据或者以前有的数据消失了)。


共享锁和排它锁

为了解决并发问题,数据库系统引入锁机制。

基本的封锁类型有两种: 排它锁 (Exclusive locks 简记为 X 锁) 和 共享锁 (Share locks 简记为 S 锁)。

 

  • 排它锁又称为写锁。若事务 T 对数据对象 A 加上 X 锁,则只允许 T 读取和修改 A,其它任何事务都不能再对 A 加任何类型的锁,直到 T 释放 A 上的锁。这就保证了其它事务在 T 释放 A 上的锁之前不能再读取和修改 A。
  • 共享锁又称为读锁。若事务 T 对数据对象 A 加上 S 锁,则事务 T 可以读 A 但不能修改 A,其它事务只能再对 A 加 S 锁,而不能加 X 锁,直到 T 释放 A 上的 S 锁。这就保证了其它事务可以读 A,但在 T 释放 A 上的 S 锁之前不能对 A 做任何修改。

 


封锁粒度

数据库中为了实现并发控制而采用封锁技术。

封锁对象的大小称为封锁粒度(Granularity)。

封锁的对象可以是逻辑单元,也可以是物理单元。以关系数据库为例子,封锁对象可以是这样一些逻辑单元:属性值、属性值的集合、元组、关系、索引项、整个索引项直至整个数据库;也可以是这样的一些物理单元:页(数据页或索引页)、物理记录等。




封锁协议与隔离级别

在运用 排他锁 和 共享锁 对数据对象加锁时,还需要约定一些规则,例如何时申请 排他锁 或 共享锁、持锁时间、何时释放等。称这些规则为封锁协议(Locking Protocol)。对封锁方式规定不同的规则,就形成了各种不同的封锁协议。不同的封锁协议对应不同的隔离级别。


一级封锁协议(对应 read uncommited)

一级封锁协议是:事务 T 在修改数据 R 之前必须先对其加 X 锁,直到事务结束才释放。事务结束包括正常结束(COMMIT)和非正常结束(ROLLBACK)。

一级封锁协议可防止丢失更新,并保证事务 T 是可恢复的。

在一级封锁协议中,如果仅仅是读数据不对其进行修改,是不需要加锁的,所以它不能保证可重复读和不读 “脏” 数据。


二级封锁协议(对应 read commited)

二级封锁协议是:一级封锁协议加上事务 T 在读取数据 R 之前必须先对其加 S 锁,读完后即可释放 S 锁(瞬间 S 锁)。

二级封锁协议除防止了丢失更新,还可进一步防止读 “脏” 数据。


三级封锁协议(对应 reapetable read)

三级封锁协议是:一级封锁协议加上事务 T 在读取数据 R 之前必须先对其加 S 锁,直到事务结束才释放。

三级封锁协议除防止了丢失更新和不读‘脏’数据外,还进一步防止了不可重复读和覆盖更新。


四级封锁协议(对应 serialization)

四级封锁协议是对三级封锁协议的增强,其实现机制也最为简单,直接对 事务中 所 读取 或者 更改的数据所在的表加表锁,也就是说,其他事务不能 读写 该表中的任何数据。这样五类并发问题都得以避免!

注:封锁协议和隔离级别并不是严格对应的。


各种隔离级别所能避免的并发问题

隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为 Read Committed。它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、幻读和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。

相关文章
|
15天前
|
SQL 关系型数据库 MySQL
乐观锁在分布式数据库中如何与事务隔离级别结合使用
乐观锁在分布式数据库中如何与事务隔离级别结合使用
|
30天前
|
SQL 数据库 数据安全/隐私保护
SQL Server数据库Owner导致事务复制log reader job无法启动的解决办法
【8月更文挑战第14天】解决SQL Server事务复制Log Reader作业因数据库所有者问题无法启动的方法:首先验证数据库所有者是否有效并具足够权限;若非,使用`ALTER AUTHORIZATION`更改为有效登录名。其次,确认Log Reader使用的登录名拥有读取事务日志所需的角色权限。还需检查复制配置是否准确无误,并验证Log Reader代理的连接信息及参数。重启SQL Server Agent服务或手动启动Log Reader作业亦可能解决问题。最后,审查SQL Server错误日志及Windows事件查看器以获取更多线索。
|
2月前
|
存储 SQL 关系型数据库
数据库事务:确保数据完整性的关键20
【7月更文挑战第20天】事务是数据库操作的基本逻辑单位,确保数据一致性。ACID原则包括:原子性(操作全成或全败),一致性(事务前后数据合法性),隔离性(并发操作互不影响),持久性(提交后更改永久保存)。MySQL的InnoDB引擎支持事务,通过undo log实现回滚,redo log确保数据持久化。开启事务可使用`BEGIN`或`START TRANSACTION`,提交`COMMIT`,回滚`ROLLBACK`。
157 70
|
10天前
|
SQL 安全 数据库
基于SQL Server事务日志的数据库恢复技术及实战代码详解
基于事务日志的数据库恢复技术是SQL Server中一个非常强大的功能,它能够帮助数据库管理员在数据丢失或损坏的情况下,有效地恢复数据。通过定期备份数据库和事务日志,并在需要时按照正确的步骤恢复,可以最大限度地减少数据丢失的风险。需要注意的是,恢复数据是一个需要谨慎操作的过程,建议在执行恢复操作之前,详细了解相关的操作步骤和注意事项,以确保数据的安全和完整。
26 0
|
2月前
|
存储 关系型数据库 MySQL
数据库并发问题17
【7月更文挑战第17天】数据库并发问题
28 3
|
2月前
|
SQL 关系型数据库 MySQL
乐观锁在分布式数据库中与事务隔离级别结合使用
乐观锁在分布式数据库中与事务隔离级别结合使用
|
1月前
|
缓存 关系型数据库 MySQL
MySQL调优秘籍曝光!从索引到事务,全方位解锁高可用秘诀,让你的数据库性能飞起来!
【8月更文挑战第6天】MySQL是顶级关系型数据库之一,其性能直接影响应用的高可用性与用户体验。本文聚焦MySQL的高性能调优,从索引设计到事务管理,逐一解析。介绍如何构建高效索引,如联合索引`CREATE INDEX idx_order_customer ON orders(order_id, customer_id);`,以及索引覆盖查询等技术。
66 0
|
2月前
|
分布式计算 数据库
现代数据库系统的并发控制与事务管理
数据库系统的并发控制与事务管理是保障数据一致性和并发访问效率的核心技术。本文深入探讨了现代数据库系统中常见的并发控制方法和事务管理机制,包括乐观并发控制和悲观并发控制,以及ACID特性的实现和应用。通过对比分析不同方法的优缺点,展示了在不同应用场景下如何选择合适的并发控制策略和事务管理方式,以达到最优的数据库性能和数据一致性。
|
2月前
|
SQL 存储 数据库
MSSQL数据库性能调优实战:索引、查询与并发控制的深度剖析
在数据库管理领域,Microsoft SQL Server(MSSQL)的性能调优是保障业务高效运行的核心任务
|
3月前
|
SQL Java 关系型数据库
JAVA数据库开发 - 事务
JAVA数据库开发 - 事务
34 0