英文:
Repository pattern with transactional query
问题
我正在编写一个可以进行事务查询的服务(在这个问题中,我将使用GORM)。
UserService
type userService struct {
UserRepository repository.IUserRepository
TokenRepository repository.ITokenRepository
}
type IUserService interface {
WithTrx() IUserService
CommitTrx() error
RollbackTrx()
Create(ctx context.Context, name string) (*model.User, error)
// ...
// ...
}
这是服务的一些实现。
user.go
func (s *userService) WithTrx() IUserService {
newService := &userService{
UserRepository: s.UserRepository.WithTrx(),
TokenRepository: s.TokenRepository,
}
return newService
}
func (s *userService) Create(ctx context.Context, name string) (*model.User, error) {
// ...
// s.UserRepository.Create()
// 然后返回用户和错误
// ...
}
而对于UserRepository.WithTrx(),基本上只是返回接口本身。
type psqlUserRepository struct {
DB *gorm.DB
}
type IUserRepository interface {
WithTrx() IUserRepository
CommitTrx() error
RollbackTrx()
Create(ctx context.Context, u model.User) (*model.User, error)
// ...
}
func (r *psqlUserRepository) WithTrx() IUserRepository {
return &psqlUserRepository{DB: r.DB.Begin()}
}
所以当我需要用户服务使用事务查询来创建用户时,我只需要:
trx := userserviceInstance.WithTrx()
user, err := trx.Create(ctx, name)
// 错误处理和回滚
commitErr := trx.CommitTrx()
是否有类似的方法?这被称为什么?我不确定这是否是创建事务查询的正确模式。
英文:
I am writing a service that can make a transactional query, (in this question I will be using GORM)
UserService
type userService struct {
UserRepository repository.IUserRepository
TokenRepository repository.ITokenRepository
}
type IUserService interface {
WithTrx() IUserService
CommitTrx() error
RollbackTrx()
Create(ctx context.Context, name string) (*model.User, error)
...
...
}
here is some implementation of the service
user.go
func (s *userService) WithTrx() IUserService {
newService := &userService{
UserRepository: s.UserRepository.WithTrx(),
TokenRepository: s.TokenRepository,
}
return newService
}
func (s *userService) Create(ctx context.Context, name string) (*model.User, error) {
...
// s.UserRepository.Create()
// then return the user, error
...
}
and for the UserRepository.WithTrx() is basically just returning the interface itself
type psqlUserRepository struct {
DB *gorm.DB
}
type IUserRepository interface {
WithTrx() IUserRepository
CommitTrx() error
RollbackTrx()
Create(ctx context.Context, u model.User) (*model.User, error)
...
}
func (r *psqlUserRepository) WithTrx() IUserRepository {
return &psqlUserRepository{DB: r.DB.Begin()}
}
So when I need user service to create a user using transactional query, I just:
trx:= userserviceInstance.WithTrx()
user, err := trx.Create(ctx, name)
// err handling and rollback
commitErr := trx.CommitTrx()
Is there any similar approach like this? What is it called? I am not sure whether this is the right pattern to create a transactional query.
答案1
得分: 3
我猜这里有几个要点。
仓储模式通常用于隐藏存储的实现细节。
事务是一个技术细节,不应该暴露给更高层。
换句话说,你的仓储接口(架构元素)不应该暴露事务(技术细节)。
是否有类似的方法?它被称为什么?我不确定这是否是创建事务查询的正确模式。
你可以了解一下工作单元模式,它对你的目的可能有用。
你可以看一下工作单元模式。
以下是一些你可能会发现有用的示例:
- https://dev.to/techschoolguru/a-clean-way-to-implement-database-transaction-in-golang-2ba
- https://goenning.net/2017/06/20/session-per-request-pattern-go/
- https://pseudomuto.com/2018/01/clean-sql-transactions-in-golang/
- https://github.com/screwyprof/skeleton/blob/main/internal/pkg/adapter/postgres/certificate_repository.go
英文:
I guess there are a few moments here.
The Repository pattern is normally used to hide the implementation details of a storage.
A Transaction is a technical detail which should not be exposed to the higher layers.
In other words the Repository interface (architectural element) you have shouldn't expose the transaction (technical details).
> Is there any similar approach like this? What is it called? I am not
> sure whether this is the right pattern to create a transactional query
You may want to learn more about Unit of Work pattern which can be useful for your purpose.
You may take a look at Unit of Work Pattern.
Bellow are some examples which you may find useful:
- https://dev.to/techschoolguru/a-clean-way-to-implement-database-transaction-in-golang-2ba
- https://goenning.net/2017/06/20/session-per-request-pattern-go/
- https://pseudomuto.com/2018/01/clean-sql-transactions-in-golang/
- https://github.com/screwyprof/skeleton/blob/main/internal/pkg/adapter/postgres/certificate_repository.go
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论