GORM 事务隔离级别配置
GORM 支持配置事务隔离级别,本文介绍其核心用法与并发处理。
什么是事务隔离级别
事务隔离级别决定多个事务并发执行时的可见性规则,级别越高,并发性能越低,但数据一致性越强。
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| ReadUncommitted | 可能 | 可能 | 可能 |
| ReadCommitted | 不可能 | 可能 | 可能 |
| RepeatableRead | 不可能 | 不可能 | 可能 |
| Serializable | 不可能 | 不可能 | 不可能 |
配置隔离级别
使用 Set 方法
Go
// 设置隔离级别为 ReadCommitted
tx := db.Session(&gorm.Session{
PrepareStmt: true,
}).Set("gorm:tx_isolation", "READ COMMITTED")
err := tx.Transaction(func(tx *gorm.DB) error {
return tx.Create(&user).Error
})
使用 Exec 设置
Go
// MySQL 方式
db.Exec("SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED")
err := db.Transaction(func(tx *gorm.DB) error {
return tx.Create(&order).Error
})
常见并发问题处理
防止幻读 - Serializable
Go
// 最高隔离级别
db.Exec("SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE")
err := db.Transaction(func(tx *gorm.DB) error {
var users []User
tx.Find(&users) // 锁定范围,防止幻读
return tx.Create(&newUser).Error
})
使用乐观锁
Go
type Product struct {
gorm.Model
Name string
Stock int
Version int `gorm:"default:0"` // 乐观锁字段
}
// GORM 插件自动处理
db.Use(optimizer.New())
tx := db.Begin()
tx.Where("id = ? AND version = ?", 1, currentVersion).
Updates(map[string]interface{}{
"stock": gorm.Expr("stock - ?", 1),
"version": gorm.Expr("version + 1"),
})
tx.Commit()
隔离级别不是越高越好,需根据业务场景权衡性能与一致性。
注意事项
- 不同数据库支持的隔离级别不同,MySQL 默认 RepeatableRead
- 高隔离级别会降低并发性能,可能引发锁等待
- 乐观锁适合读多写少场景,悲观锁适合写密集场景
- 隔离级别应在事务开启前设置,事务中修改无效
要点总结
- 隔离级别从 ReadUncommitted 到 Serializable 逐步增强
- 使用
Session或Exec配置隔离级别 - 高隔离级别解决并发问题但降低性能
- 可配合乐观锁、悲观锁处理特定场景
文章存放路径:D:\git2\jwdev\articles\GORM\进阶\事务处理\事务隔离级别配置.md
📝 发现内容有误?点击此处直接编辑