MySQL数据库笔记——版本号机制和CAS(Compare And Swap)

大家好,这里是编程Cookbook,关注公众号「编程Cookbook」,获取更多面试资料。本文详细介绍乐观锁的两种实现方式:版本号机制和CAS(Compare And Swap)。



MySQL 内置的并发控制机制

关注公众号「编程Cookbook」,获取更多编程学习/面试资料!

MySQL 内置了强大的并发控制机制,例如 MVCC(多版本并发控制) 和锁机制。这些机制在更高层次上实现了并发控制。自动处理事务隔离和并发冲突,适用于复杂数据库事务管理。

MVCC(多版本并发控制)

  • 核心:基于事务 ID 和 Undo Log,实现高效的读写并发。
  • 特点:快照读无需加锁,写操作使用回滚日志实现隔离性。

MVCC的详细信息参考:《MySQL数据库——多版本并发控制MVCC》

锁机制

  1. 按锁粒度表锁行锁(InnoDB 默认)。

  2. 按锁类型共享锁(S 锁)排他锁(X 锁)

  3. 意向锁:用于标记表中是否有行级锁,避免加锁冲突。

  4. 按加锁机制分:悲观锁和乐观锁。

    • 悲观锁:通过显式加锁防止并发冲突。
    • 乐观锁:通过版本号机制和CAS实现,本文重点

锁的详细信息参考:《MySQL数据库——锁的分类》

总结

版本号机制、CAS和MVCC 的实现方式在不同层面有区别。以下是对它们在 程序员实现MySQL 内部支持 上的区别详细分析:

机制程序员实现MySQL 支持
版本号机制程序员设计表结构,手动添加 version 字段和条件更新MySQL 不直接支持,由程序员通过 SQL 手动实现
CAS程序员通过 SQL 条件更新模拟类似行为MySQL 不支持硬件级 CAS,仅能通过条件更新实现
MVCC程序员无需手动实现MySQL 内置支持,通过事务 ID 和 Undo Log 实现
  • 程序员实现的版本号机制和 CAS
    • 需要手动设计表结构、编写 SQL。
    • 适用于轻量级业务逻辑的并发控制。

乐观锁实现方式(需要手动实现)

关注公众号「编程Cookbook」,获取更多编程学习/面试资料!

版本号机制CAS(Compare And Swap) 是实现 乐观锁 的两种常见方式,它们的核心思想是通过条件检查来保证并发安全。以下是两种方法的实现详细介绍:


1. 版本号机制

MySQL 本身并未内置对 版本号机制 的直接支持。版本号机制通常由应用程序开发人员在数据库设计和操作层手动实现

基本原理

  • 为每一条记录添加一个额外的字段版本号)。
  • 在更新数据时,先检查版本号是否与读取时一致,再执行更新。
  • 版本号的变化表明数据已经被其他事务修改,当前事务需要重新尝试或放弃。
实现步骤
  1. 读取数据和版本号

    • 查询需要更新的记录,并获取当前版本号。
    SELECT version, value FROM table_name WHERE id = 1;
    
  2. 检查版本号并更新

    • 在更新时,检查版本号是否一致。
    • 如果一致,执行更新并将版本号加 1。
    UPDATE table_name
    SET value = 'new_value', version = version + 1
    WHERE id = 1 AND version = 10;
    
  3. 处理并发冲突(如果存在)

    • 如果 WHERE 子句中的 version 不匹配,说明该记录已被其他事务修改,当前事务更新失败。
示例

假设表结构如下:

CREATE TABLE table_name (
    id INT PRIMARY KEY,
    value VARCHAR(255),
    version INT
);

事务 A:

SELECT version, value FROM table_name WHERE id = 1; -- 返回 version = 10
UPDATE table_name SET value = 'new_value', version = version + 1 WHERE id = 1 AND version = 10;

事务 B(同时运行):

SELECT version, value FROM table_name WHERE id = 1; -- 返回 version = 10
UPDATE table_name SET value = 'another_value', version = version + 1 WHERE id = 1 AND version = 10; -- 更新失败
优缺点
  • 优点
    • 不需要加锁,性能高。
    • 简单易实现。
  • 缺点
    • 需要额外的字段存储版本号。
    • 并发冲突时,需要重试或回滚,可能增加系统开销。

2. CAS(Compare And Swap)

MySQL 不直接支持类似硬件级别的 CAS 操作。对于类似 CAS 的功能,依赖程序员通过代码实现【也有说通过 SQL 实现】。

基本原理

  • CAS 是一种原子操作,用于更新某个值时,先比较当前值是否符合预期。
  • 如果当前值符合预期,则执行更新,否则不更新。
实现步骤
  1. 读取数据的当前值

    • 获取目标变量的当前值。
  2. 比较值是否符合预期

    • 如果当前值与预期值一致,说明没有其他线程修改过该值。
  3. 更新数据

    • 在当前值符合预期时,执行更新。
    • 如果值不一致,操作失败,可以选择重试。
示例:Go 中 CAS 实现

Go 中的 CAS 使用 sync/atomic 包提供的 CompareAndSwap 系列方法。

package main

import (
	"fmt"
	"sync/atomic"
)

func main() {
	var counter int32 = 10

	// 期望值是 10,新值是 11
	success := atomic.CompareAndSwapInt32(&counter, 10, 11)

	if success {
		fmt.Printf("Update successful, new value: %d\n", counter)
	} else {
		fmt.Printf("Update failed, current value: %d\n", counter)
	}
}

补充:也有说可以通过SQL实现,SQL实现,本质上和版本号机制一样,不一样的点在于不需要额外字段,直接操作数据值(count)。如下:

-- 假设表结构如下:
CREATE TABLE counter (
    id INT PRIMARY KEY,
    count INT );

-- 当前 count = 10 
UPDATE counter SET count = count + 1 WHERE id = 1 AND count = 10; 
优缺点
  • 优点
    • 无需加锁,性能高。
    • 操作是原子的,由硬件保证一致性。
  • 缺点
    • 存在 ABA 问题(值从 A 改为 B,又改回 A,CAS 不会察觉)。
    • 如果冲突频繁,可能导致多次重试。

3. 版本号机制 vs CAS

特性版本号机制CAS
实现方式基于字段的版本号,依赖 SQL 条件更新或程序逻辑基于硬件支持的原子操作,直接比较并更新
字段要求需要额外的版本号字段(version不需要额外字段,直接操作数据值
适用场景数据库或程序语言中的并发控制程序语言中的并发控制,数据库中可通过条件更新模拟
是否依赖数据库通常依赖 SQL 实现,但也可在程序中实现不依赖数据库,可直接通过程序实现
优点简单易用,适合数据库复杂业务场景高性能,无需锁,硬件原子操作支持
缺点存在重试开销,版本号字段增加存储开销存在 ABA 问题,冲突频繁时重试代价较高

两者适用于不同的场景,但核心思想相同:通过比较条件,确保操作的正确性。

关注公众号「编程Cookbook」,获取更多编程学习/面试资料!

历史文章

  1. MySQL数据库笔记——数据库三范式
  2. MySQL数据库笔记——存储引擎(InnoDB、MyISAM、MEMORY、ARCHIVE)
  3. MySQL数据库笔记——常见的几种锁分类
  4. MySQL数据库笔记——索引介绍
  5. MySQL数据库笔记——事务介绍
  6. MySQL数据库笔记——索引结构之B+树
  7. MySQL数据库笔记——索引潜规则(回表查询、索引覆盖、索引下推)
  8. MySQL数据库笔记——索引潜规则(最左前缀原则)
  9. MySQL数据库笔记——常见慢查询优化方式
  10. MySQL数据库笔记——日志介绍
  11. MySQL数据库笔记——多版本并发控制MVCC
  12. MySQL数据库笔记——主从复制
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值