全部学科
Python全栈
python
NodeJS全栈
nodejs
📝 1 篇文章 20 道配套习题

高级并发与锁机制专题

专题说明

本专题深入讲解GORM在高并发场景下的锁机制与事务控制,涵盖悲观锁、乐观锁、分布式锁、事务隔离级别等高级并发控制技术。

学习目标

  1. 掌握悲观锁与乐观锁的原理与GORM实现
  2. 学会事务隔离级别的选择与应用
  3. 理解分布式锁在GORM中的实现方案

学习内容

本专题涵盖以下知识点:

  • 悲观锁(SELECT FOR UPDATE)
  • 乐观锁(版本号机制)
  • 事务隔离级别与并发问题
  • 分布式锁实现
  • 死锁检测与预防

学习建议

  1. 先理解并发控制的理论基础,再学习GORM的具体实现
  2. 重点掌握悲观锁与乐观锁的适用场景差异
  3. 结合实际业务分析锁粒度与性能的平衡

📝 配套习题(20 题)

💡 参考答案在文末
判断题
1

在 InnoDB 存储引擎中,SELECT FOR UPDATE 一定只锁定查询条件匹配的行,不会影响其他行。

A

B

单选题
2

在 GORM 中实现基于数据库的分布式锁,推荐方式是?

A

使用唯一键插入锁记录(INSERT IGNORE 或 ON CONFLICT DO NOTHING)

B

使用 SELECT FOR UPDATE

C

使用 Redis 分布式锁

D

使用文件锁

3

在 GORM 中实现基于数据库的分布式锁,推荐方式是?

A

使用唯一键插入锁记录(INSERT IGNORE 或 ON CONFLICT DO NOTHING)

B

使用 SELECT FOR UPDATE

C

使用 Redis 分布式锁

D

使用文件锁

4

当一个事务等待获取悲观锁时,如果另一个持有锁的事务长时间不释放,会发生什么?

A

等待事务会立即报错

B

等待事务会一直阻塞,直到数据库的锁等待超时设置(lock_wait_timeout)触发

C

GORM 会自动超时并释放

D

数据库会自动升级锁为表级锁

5

在 GORM 中,如何对查询记录加行级排他锁(SELECT FOR UPDATE)?

A

db.Where("id = ?", 1).Locking("FOR UPDATE").First(&user)

B

db.Clauses(clause.Locking{Strength: "UPDATE"}).Where("id = ?", 1).First(&user)

C

db.Raw("SELECT * FROM users WHERE id = 1 FOR UPDATE").Scan(&user)

D

db.Where("id = ?", 1).First(&user, clauselocking.Update)

6

在 GORM 中实现基于数据库的分布式锁,推荐方式是?

A

使用唯一键插入锁记录(INSERT IGNORE 或 ON CONFLICT DO NOTHING)

B

使用 SELECT FOR UPDATE

C

使用 Redis 分布式锁

D

使用文件锁

7

在 MySQL 8.0+ 中,如何跳过已被锁定的行,只查询未被锁定的行?

A

db.Clauses(clause.Locking{Strength: "UPDATE", Options: "SKIP LOCKED"}).Find(&records)

B

db.Where("locked = false").Find(&records)

C

无法实现,必须使用乐观锁

D

db.Clauses(clause.Locking{Strength: "SHARE"}).Find(&records)

8

在 GORM 中实现基于数据库的分布式锁时,释放锁的操作需要注意什么关键问题?

A

释放前必须验证锁的归属权,确保是锁的持有者才能释放

B

直接执行 DELETE 语句删除锁记录即可

C

依赖数据库事务提交自动释放锁

D

通过设置超时时间让锁自动过期,无需手动释放

9

在 GORM 中,如何对查询加共享锁(SELECT FOR SHARE)?

A

db.Clauses(clause.Locking{Strength: "SHARE"}).Where("id = ?", 1).First(&user)

B

db.Clauses(clause.Locking{Strength: "READ"}).Where("id = ?", 1).First(&user)

C

db.Where("id = ?", 1).First(&user, gorm.ShareLock)

D

db.Lock("SHARE").Where("id = ?", 1).First(&user)

10

在 GORM 中实现基于数据库的分布式锁,推荐方式是?

A

使用唯一键插入锁记录(INSERT IGNORE 或 ON CONFLICT DO NOTHING)

B

使用 SELECT FOR UPDATE

C

使用 Redis 分布式锁

D

使用文件锁

11

在 GORM 中实现基于数据库的分布式锁,推荐方式是?

A

使用唯一键插入锁记录(INSERT IGNORE 或 ON CONFLICT DO NOTHING)

B

使用 SELECT FOR UPDATE

C

使用 Redis 分布式锁

D

使用文件锁

12

在 GORM 中实现基于数据库的分布式锁,推荐方式是?

A

使用唯一键插入锁记录(INSERT IGNORE 或 ON CONFLICT DO NOTHING)

B

使用 SELECT FOR UPDATE

C

使用 Redis 分布式锁

D

使用文件锁

13

在 GORM 中实现基于数据库的分布式锁,推荐方式是?

A

使用 INSERT IGNORE 或 ON CONFLICT DO NOTHING

B

使用 SELECT FOR UPDATE

C

使用 Redis 分布式锁

D

使用文件锁

14

在 GORM 中实现基于数据库的分布式锁,推荐方式是?

A

使用 INSERT IGNORE 或 ON CONFLICT DO NOTHING

B

使用 SELECT FOR UPDATE

C

使用 Redis 分布式锁

D

使用文件锁

15

在 GORM 中实现基于数据库的分布式锁,推荐方式是?

A

使用唯一键插入锁记录(INSERT IGNORE 或 ON CONFLICT DO NOTHING)

B

使用 SELECT FOR UPDATE

C

使用 Redis 分布式锁

D

使用文件锁

多选题
16

关于悲观锁与数据库事务隔离级别的关系,以下哪些描述是正确的?

A

SELECT FOR UPDATE 在所有隔离级别下都能正常工作

B

在 READ COMMITTED 隔离级别下,使用 FOR UPDATE 可以防止脏读和不可重复读

C

FOR UPDATE 锁会在事务提交后自动释放

D

FOR UPDATE 可以防止其他事务对同一行执行 UPDATE 或 DELETE

17

在高并发场景下,过度使用悲观锁可能导致哪些问题?

A

事务串行化执行,系统吞吐量大幅下降

B

锁等待超时错误频发

C

死锁概率增加

D

数据库连接池耗尽

18

以下哪些场景适合使用悲观锁?

A

库存扣减:多个并发请求同时扣减同一商品库存

B

用户信息查询:多个用户同时查看同一用户资料

C

账户余额转账:从一个账户扣款同时向另一个账户加款

D

计数器自增:页面访问次数统计

填空题
19

使用悲观锁扣减库存:

Go
db.!!1_Transaction!!(func(tx *gorm.DB) error {
    var product Product
    tx.Clauses(clause.Locking{!!2_Strength!!: "UPDATE"}).
        Where("id = ?", productID).First(&product)
    if product.Stock < quantity {
        return errors.New("库存不足")
    }
    product.Stock -= quantity
    return tx.!!3_Save!!(&product).Error
})
简答题
20

设计一个基于悲观锁的库存扣减系统,需要处理以下要求:

  1. 支持批量扣减(一次扣减多种商品)
  2. 防止超卖
  3. 避免死锁
  4. 设置合理的锁超时

请给出完整的代码实现,并说明如何避免死锁。

参考答案
1.错误 2.A 3.A 4.B 5.B 6.A 7.A 8.A 9.A 10.A 11.A 12.A 13.A 14.A 15.A 16.B;C;D 17.A;B;C;D 18.A;C 19.Transaction;Strength;Save 20.
想在手机上练习这套专题?
使用微信卷王开发者小程序,打开首页顶部扫码功能识别二维码
← 上一个专题 错误处理与日志专题
下一个专题 → 高级查询技术专题
扫码体验小程序
加载中
想在手机上刷题学习?
使用微信卷王开发者小程序,打开首页顶部扫码功能识别二维码