Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database 由于这种模式,在同一个结构中使用事务和简单数据库连接,我能做什么?_Database_Go_Transactions_Go Gorm_Go Pg - Fatal编程技术网

Database 由于这种模式,在同一个结构中使用事务和简单数据库连接,我能做什么?

Database 由于这种模式,在同一个结构中使用事务和简单数据库连接,我能做什么?,database,go,transactions,go-gorm,go-pg,Database,Go,Transactions,Go Gorm,Go Pg,我发现使用干净的体系结构方法 这家伙正在使用 Gorm对于DB连接和事务具有相同的类型,例如: var db*gorm.db 变量tx*gorm.DB 我是你的粉丝。但这里的类型不同(可能更好),例如: var db*pg.db 变量tx*pg.tx 当然错误是:不能将'tx'(type*tx)用作type*pg.DB 小复制品: 主程序包 进口( “github.com/go pg/pg/v10” ) 类型播放器结构{ ID int 名称字符串 } 类型PlayerRepo结构{ db*p

我发现使用干净的体系结构方法

这家伙正在使用

Gorm对于DB连接和事务具有相同的类型,例如:

var db*gorm.db
变量tx*gorm.DB
我是你的粉丝。但这里的类型不同(可能更好),例如:

var db*pg.db
变量tx*pg.tx
当然错误是:
不能将'tx'(type*tx)用作type*pg.DB

小复制品:

主程序包
进口(
“github.com/go pg/pg/v10”
)
类型播放器结构{
ID int
名称字符串
}
类型PlayerRepo结构{
db*pg.db
teamRepo*teamRepo
}
类型TeamRepo结构{
db*pg.db
}
func NewPlayerRepo(db*pg.db)*PlayerRepo{
return&PlayerRepo{
db:db,
teamRepo:NewTeamRepo(db),
}
}
func新团队报告(db*pg.db)*团队报告{
return&TeamRepo{db:db}
}
func(r*PlayerRepo)Find(id int)(*Player,error){
var播放器
err:=r.db.Model(&player)。其中(“id=?”,id)。选择()
如果错误!=零{
返回零,错误
}
回归&球员,零
}
func(r*PlayerRepo)All()([]*播放器,错误){
//长代码
返回零,零
}
func(r*PlayerRepo)Insert()(*Player,错误){
//长代码
返回零,零
}
func(r*PlayerRepo)Update()(*Player,错误){
//长代码
返回零,零
}
func(r*PlayerRepo)Delete()(*Player,错误){
//长代码
返回零,零
}
带事务的func(r*PlayerRepo)(txFunc(*PlayerRepo)错误)(错误){
tx,u:=r.db.Begin()

manager:=NewPlayerRepo(tx)//您可以定义一个接口,该接口已经由以下两种方式隐式实现:

type数据库接口{
Begin()(*Tx,错误)
Close()错误
Context()Context.Context
CopyFrom(r io.Reader,查询接口{},参数…接口{})(res Result,err error)
CopyTo(w io.Writer,查询接口{},参数…接口{})(res Result,err error)
Exec(查询接口{},参数…接口{})(结果,错误)
ExecContext(c context.context,查询接口{},参数…接口{})(结果,错误)
ExecOne(查询接口{},参数…接口{})(结果,错误)
ExecuteContext(c context.context,查询接口{},参数…接口{})(结果,错误)
Formatter()orm.QueryFormatter
模型(模型…接口{})*orm.Query
ModelContext(c context.context,model…interface{})*orm.Query
准备(q字符串)(*Stmt,错误)
查询(模型接口{},查询接口{},参数…接口{})(结果,错误)
QueryContext(c context.context,模型接口{},查询接口{},参数…接口{})(结果,错误)
QueryOne(模型接口{},查询接口{},参数…接口{})(结果,错误)
QueryOneContext(c context.context,模型接口{},查询接口{},参数…接口{})(结果,错误)
RunInTransaction(ctx context.context,fn func(*Tx)error)错误
}
注意:我只知道方法名称匹配,我没有检查签名是否也匹配,如果不匹配,则需要相应地编辑接口

您可以添加一个简单的“编译器检查”:

var\udb=(*pg.DB)(无)
var_uDB=(*pg.Tx)(无)
然后,您可以将
PlayerRepo.db
字段的类型从
*pg.db
更改为新的
db
界面

类型PlayerRepo结构{
分贝
teamRepo*teamRepo
}
类型TeamRepo结构{
分贝
}
func NewPlayerRepo(db)*PlayerRepo{
return&PlayerRepo{
db:db,
teamRepo:NewTeamRepo(db),
}
}
func新团队报告(db)*团队报告{
return&TeamRepo{db:db}
}
带事务的func(r*PlayerRepo)(txFunc(*PlayerRepo)错误)(错误){
tx,err:=r.db.Begin()
如果错误!=零{
返回错误
}
延迟函数(){
//出错时回滚;无错误时提交
}()
经理:=NewPlayerRepo(德克萨斯州)
err=txFunc(管理器)
返回
}

如果您的回购类型需要能够调用一些对
pg.DB
pg.Tx
都不通用的方法,因此新的
DB
接口没有定义,那么一种方法就是保留原始类型以供使用,例如:

类型PlayerRepo结构{
分贝
pg*pg.DB
teamRepo*teamRepo
}
类型TeamRepo结构{
分贝
pg*pg.DB
}
func NewPlayerRepo(db-db,pg*pg.db)*PlayerRepo{
return&PlayerRepo{
db:db,
pg:pg,
teamRepo:NewTeamRepo(db,pg),
}
}
func新团队报告(db db,pg*pg.db)*团队报告{
return&TeamRepo{db:db,pg:pg}
}
带事务的func(r*PlayerRepo)(txFunc(*PlayerRepo)错误)(错误){
tx,err:=r.db.Begin()
如果错误!=零{
返回错误
}
延迟函数(){
//出错时回滚;无错误时提交
}()
经理:=NewPlayerRepo(德克萨斯州,右后卫)
err=txFunc(管理器)
返回
}

请注意,如果您决定使用
orm.DB
,这是合理的,但是它缺少了一些您需要的并且已经由
pg.DB
pg.Tx
实现的方法,那么您可以将
orm.DB
嵌入到自定义接口中,并只添加缺少的方法

type数据库接口{
Begin()(*Tx,错误)
orm.DB
}

您可以定义一个接口,该接口已经由以下两种方式隐式实现:

type数据库接口{
Begin()(*Tx,错误)
Close()错误
Context()Context.Context
CopyFrom(r io.Reader,查询接口{},参数…接口{})(res Result,err error)
CopyTo(w io.Writer,查询接口{},参数…接口{})(res Result,err error)
Exec(查询接口{},参数…接口{})(结果,错误)
ExecContext(c context.context,查询接口{},参数…interf