关系型数据库主要通过事务、隔离级别和锁机制来管理并发访问。事务将操作组合成原子工作单元,确保所有更改要么一起成功(提交),要么一起失败(回滚)。隔离级别通过控制未提交更改的可见性来定义事务之间如何相互作用。例如,读已提交 (Read Committed) 级别确保事务只能看到在其开始之前已提交的数据,从而防止“脏读”(访问未提交的更改)。像可重复读 (Repeatable Read) 这样的更高级别可以防止不可重复读(事务期间行数据发生变化),而可串行化 (Serializable) 则强制执行严格排序以避免冲突。这些设置在一致性和性能之间取得平衡——更严格的隔离会降低并发性,但能最大程度地减少异常。
锁定是另一种核心机制。数据库使用锁来限制在写入或读取期间对数据的访问。排他锁 (Exclusive locks) 阻止其他事务在行被更新时修改或读取该行,而共享锁 (shared locks) 允许并发读取但阻止写入。例如,当用户在 MySQL 中更新一行时,数据库会在该行上放置排他锁,迫使其他写入请求等待。锁的粒度各不相同——行级锁(在 PostgreSQL 中常见)允许更细粒度的并发,而表级锁(在旧系统中常见)更简单但限制吞吐量。当事务持有锁并等待彼此的资源时,可能会发生死锁。数据库通过终止其中一个事务(通过超时或死锁检测)或要求重试来解决这个问题。
多版本并发控制 (MVCC) 是一种流行的替代锁定机制的方法。MVCC 不会阻塞访问,而是维护行的多个版本。读取者看到其事务开始时数据库的快照,而写入者创建新的版本。PostgreSQL 使用这种方法:SELECT
查询从一致的快照读取数据,避免与并发更新发生冲突。这减少了争用,但增加了存储开销并需要进行清理(例如,PostgreSQL 的 vacuum 进程)。MVCC 对于读密集型工作负载效果很好,但在较低的隔离级别下可能导致“幻读”(后续查询中出现新行)。开发人员根据其应用程序的读写模式和一致性需求在锁定和 MVCC 之间进行选择。例如,银行系统可能优先选择严格锁定,而分析平台则倾向于使用 MVCC 以提高可伸缩性。