高级并发与锁机制专题测试
考察知识点
- 乐观锁与版本号机制
- 悲观锁与 SELECT FOR UPDATE
- 行级锁与表级锁
- 并发安全与竞态条件
💡 参考答案在文末
判断题
1
使用 Version 字段的乐观锁可以完全避免 ABA 问题。
2
在 InnoDB 存储引擎中,SELECT FOR UPDATE 一定只锁定查询条件匹配的行,不会影响其他行。
单选题
3
当乐观锁更新失败时,最佳的重试策略是什么?
4
在 GORM 中,如何对查询记录加行级排他锁(SELECT FOR UPDATE)?
5
如果一个记录需要同时基于 Version 和 Status 字段做乐观锁控制(确保只更新状态为 "pending" 的记录),应该如何写?
6
在事务中使用乐观锁时,版本号检查应该在什么时候执行?
7
在 MySQL 8.0+ 中,如何跳过已被锁定的行,只查询未被锁定的行?
8
在 GORM 中,如何对查询加共享锁(SELECT FOR SHARE)?
9
乐观锁的核心思想是什么?
10
当一个事务等待获取悲观锁时,如果另一个持有锁的事务长时间不释放,会发生什么?
多选题
11
以下哪些场景适合使用悲观锁?
12
在 GORM 中,实现乐观锁的方式有哪些?
13
在高并发场景下,过度使用悲观锁可能导致哪些问题?
14
在以下哪些场景中,乐观锁比悲观锁更合适?
15
与悲观锁相比,乐观锁有哪些性能优势?
16
关于悲观锁与数据库事务隔离级别的关系,以下哪些描述是正确的?
填空题
17
使用 Version 字段实现乐观锁:
Go
type Product struct {
ID uint
Stock int
Version int `____________`
}
func UpdateStock(db *gorm.DB, id uint, deduct int, currentVersion int) error {
result := db.Model(&Product{}).
Where("id = ? AND ____________ = ?", id, currentVersion).
Updates(map[string]interface{}{
"stock": gorm.Expr("stock - ?", deduct),
"version": gorm.Expr("version + ____________"),
})
if result.RowsAffected == 0 {
return errors.New("数据已被其他事务修改")
}
return nil
}
18
使用悲观锁扣减库存:
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
})
简答题
19
设计一个基于悲观锁的库存扣减系统,需要处理以下要求:
- 支持批量扣减(一次扣减多种商品)
- 防止超卖
- 避免死锁
- 设置合理的锁超时
请给出完整的代码实现,并说明如何避免死锁。
20
请实现一个通用的乐观锁重试函数,要求:
- 支持自定义最大重试次数
- 带指数退避策略
- 接受一个包含读取-修改-更新逻辑的回调函数
- 返回最终的错误或成功结果
参考答案
1.正确
2.错误
3.C
4.B
5.A
6.C
7.A
8.A
9.B
10.B
11.A;C
12.A;C;D
13.A;B;C;D
14.A;C
15.A;B;D
16.B;C;D
17.gorm:"default:1";version;1
18.Transaction;Strength;Save
19.略
20.略
想在手机上练习这套试卷?
使用微信卷王开发者小程序,打开首页顶部扫码功能识别二维码