事务和Hook
1. 会话Session
为了避免共用db导致的一些问题,gorm提供了会话模式,通过新建session的形式,将db的操作分离,互不影响。
创建session的时候,有一些配置:
// Session 配置
type Session struct {
DryRun bool //生成 SQL 但不执行
PrepareStmt bool //预编译模式
NewDB bool //新db 不带之前的条件
Initialized bool //初始化新的db
SkipHooks bool //跳过钩子
SkipDefaultTransaction bool //禁用默认事务
DisableNestedTransaction bool //禁用嵌套事务
AllowGlobalUpdate bool //允许不带条件的更新
FullSaveAssociations bool //允许更新关联数据
QueryFields bool //select(字段)
Context context.Context
Logger logger.Interface
NowFunc func() time.Time //允许改变 GORM 获取当前时间的实现
CreateBatchSize int
}
比如说可以禁用默认的事务,从而提供性能,官方说大致能提升30%左右:
// 持续会话模式
tx := db.Session(&Session{
SkipDefaultTransaction: true})
tx.First(&user, 1)
tx.Find(&users)
tx.Model(&user).Update("Age", 18)
比如使用PreparedStmt
在执行任何 SQL 时都会创建一个 prepared statement 并将其缓存,以提高后续的效率
// 会话模式
tx := db.Session(&Session{
PrepareStmt: true})
tx.First(&user, 1)
tx.Find(&users)
tx.Model(&user).Update("Age", 18)
// returns prepared statements manager
stmtManger, ok := tx.ConnPool.(*PreparedStmtDB)
// 关闭 *当前会话* 的预编译模式
stmtManger.Close()
// 为 *当前会话* 预编译 SQL
stmtManger.PreparedSQL // => []string{}
// 为当前数据库连接池的(所有会话)开启预编译模式
stmtManger.Stmts // map[string]*sql.Stmt
for sql, stmt := range stmtManger.Stmts