-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #19 from xmgtony/develop
✨ 添加多service方法事务支持
- Loading branch information
Showing
12 changed files
with
186 additions
and
66 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// author: xmgtony | ||
// date: 2023-06-29 14:47 | ||
// version: | ||
|
||
package mysql | ||
|
||
import ( | ||
"apiserver-gin/pkg/config" | ||
"apiserver-gin/pkg/db" | ||
"context" | ||
"gorm.io/gorm" | ||
) | ||
|
||
// var _ IDataSource = new(*defaultMysqlDataSource) 也可 | ||
var _ db.IDataSource = (*defaultMysqlDataSource)(nil) | ||
|
||
// defaultMysqlDataSource 默认mysql数据源实现 | ||
type defaultMysqlDataSource struct { | ||
master *gorm.DB // 定义私有属性,用来持有主库链接,防止每次创建,创建后直接返回该变量。 | ||
slave *gorm.DB // 同上,从库链接 | ||
} | ||
|
||
func (d *defaultMysqlDataSource) Master(ctx context.Context) *gorm.DB { | ||
// 事物, 根据事物的key取出tx | ||
tx, ok := ctx.Value(contextTxKey{}).(*gorm.DB) | ||
if ok { | ||
return tx | ||
} | ||
if d.master == nil { | ||
panic("The [master] connection is nil, Please initialize it first.") | ||
} | ||
return d.master | ||
} | ||
|
||
func (d *defaultMysqlDataSource) Slave(ctx context.Context) *gorm.DB { | ||
tx, ok := ctx.Value(contextTxKey{}).(*gorm.DB) | ||
if ok { | ||
return tx | ||
} | ||
if d.slave == nil { | ||
panic("The [slave] connection is nil, Please initialize it first.") | ||
} | ||
return d.slave | ||
} | ||
|
||
func (d *defaultMysqlDataSource) Close() { | ||
// 关闭主库链接 | ||
if d.master != nil { | ||
m, err := d.master.DB() | ||
if err != nil { | ||
_ = m.Close() | ||
} | ||
} | ||
// 关闭从库链接 | ||
if d.slave != nil { | ||
s, err := d.slave.DB() | ||
if err != nil { | ||
_ = s.Close() | ||
} | ||
} | ||
} | ||
|
||
func NewDefaultMysql(c config.DBConfig) *defaultMysqlDataSource { | ||
return &defaultMysqlDataSource{ | ||
master: db.GetMysqlConn( | ||
c.Username, | ||
c.Password, | ||
c.Host, | ||
c.Port, | ||
c.Dbname, | ||
c.MaximumPoolSize, | ||
c.MaximumIdleSize), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// Created on 2023/3/15. | ||
// @author tony | ||
// email [email protected] | ||
// description 事物控制接口 | ||
|
||
package mysql | ||
|
||
import ( | ||
"apiserver-gin/pkg/db" | ||
"context" | ||
"gorm.io/gorm" | ||
) | ||
|
||
type contextTxKey struct{} | ||
|
||
// 事物默认实现 | ||
type transaction struct { | ||
ds db.IDataSource | ||
} | ||
|
||
func NewTransaction(_ds db.IDataSource) *transaction { | ||
return &transaction{ds: _ds} | ||
} | ||
|
||
func (t *transaction) Execute(ctx context.Context, fn func(ctx context.Context) error) error { | ||
return t.ds.Master(ctx).Transaction(func(tx *gorm.DB) error { | ||
withValue := context.WithValue(ctx, contextTxKey{}, tx) | ||
return fn(withValue) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// author: xmgtony | ||
// date: 2023-06-29 15:00 | ||
// version: 事务操作演示 | ||
|
||
package service | ||
|
||
import ( | ||
"apiserver-gin/pkg/db" | ||
"context" | ||
) | ||
|
||
// TxDemoService txDemo服务接口 | ||
type TxDemoService interface { | ||
SaveWithTx(ctx context.Context) | ||
} | ||
|
||
// txDemoService 默认实现 | ||
type txDemoService struct { | ||
userService UserService | ||
billService AccountBillService | ||
tx db.Transaction | ||
} | ||
|
||
func NewTxDemoService(us UserService, bs AccountBillService, tx db.Transaction) *txDemoService { | ||
return &txDemoService{ | ||
userService: us, | ||
billService: bs, | ||
tx: tx, | ||
} | ||
} | ||
|
||
func (tds *txDemoService) SaveWithTx(ctx context.Context) { | ||
err := tds.tx.Execute(ctx, func(context context.Context) error { | ||
// TODO 这里只是举例,实际请根据业务执行多个service操作 | ||
// 操作1 | ||
// tds.userService.Save(context, user) | ||
// 操作2 | ||
// tds.billService.Save(context, bill) | ||
//if (条件1) { | ||
// 返回err则回滚事务 | ||
// return err | ||
//} | ||
return nil | ||
}) | ||
if err != nil { | ||
// 处理error | ||
return | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// author: xmgtony | ||
// date: 2023-06-29 14:38 | ||
// version: 事务接口 | ||
|
||
package db | ||
|
||
import "context" | ||
|
||
// Transaction 事物接口 | ||
type Transaction interface { | ||
// Execute 执行一个事务方法,func为一个需要保证事务完整性的业务方法 | ||
Execute(ctx context.Context, fn func(ctx context.Context) error) error | ||
} |