事务接口定义

GoooQo中的事务管理通过TransactionManagerTransactionContext(以下简称TC)配合完成。

package core

import (
	"context"
	"database/sql/driver"
)

type TransactionManager interface {
	GetClient() any
	StartTransaction(ctx context.Context) (TransactionContext, error)
	SubmitTransaction(ctx context.Context, callback func(tc TransactionContext) error) error
}

type TransactionContext interface {
	context.Context
	driver.Tx
	Parent() context.Context
	SavePoint(name string) error
	RollbackTo(name string) error
}

TransactionManager中的方法StartTransaction负责开启事务并返回TC;TC组合了driver.Tx,负责事务的提交和回滚。

TxDataAccess接口组合了DataAccessTransactionManager,可以在实现数据库访问接口的同时,更方便的进行事务管理。

type TxDataAccess[E Entity] interface {
    TransactionManager
    DataAccess[E]
}

事务使用示例

用户可以使用StartTransaction开启事务,手动提交或者回滚事务:

tc, err := userDataAccess.StartTransaction(ctx)
userQuery := UserQuery{ScoreLt: P(80)}
cnt, err := userDataAccess.DeleteByQuery(tc, userQuery)
if err != nil {
	err = RollbackFor(tc, err)
	return 0
}
err = tc.Commit()
return cnt

或者使用TransactionManager#SubmitTransaction通过回调的方式提交事务:

err := tm.SubmitTransaction(ctx, func(tc TransactionContext) (err error) {
    // transaction body
    return
})

事务的传播管理

在Spring的事务传播机制中定义了以下7个级别,GoooQo中的对应处理方式如下:

  • REQUIRED

    使用任意context调用TxDataAccessStartTransaction

    如果context为TC,则将context强制转化为TC后返回;

    如果context不是TC,则调用db#BeginTx开启事务获取sql.Tx,再通过context和sql.Tx创建TC后返回。

  • SUPPORTS

    使用任意Context调用TxDataAccess的数据库访问方法。

  • REQUIRES_NEW

    ctx为TC时,使用ctx.(TC).Context开启事务;
    ctx不为TC时,使用ctx开启事务;

  • NOT_SUPPORTED

    ctx为TC时,使用ctx.(TC).Context调用TxDataAccess的数据库访问方法;
    ctx不为TC时,使用ctx调用TxDataAccess的数据库访问方法;

  • MANDATORY:

    对传入的ctx不是TC的情况进行处理。

  • NEVER

    对传入的ctx是TC的情况进行处理。

  • NESTED

    使用TC的SavePoint/RollbackTo方法。

这里整理了一个表格对前4个传播级别进行了对比:

context参数\数据库操作 开启事务 调用数据库
任意Context REQUIRED SUPPORTS
ctx.(TC).Context | ctx REQUIRES_NEW NOT_SUPPORTED

总结

虽然由于Golang语法限制,无法实现类似SpringTx提供的基于注解的管理事务传播级别的方法,
但是GoooQo利用了Golang的Context机制达到了同样的效果,使得开发人员能够使用最少的代码来对事务的传播级别进行对应的处理。


© 2024 Yuan Zhen. All rights reserved.