Шаблон репозитория с транзакционным запросом
Я пишу сервис, который может выполнять транзакционный запрос (в этом вопросе я буду использовать 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()
// then return the user, error
...
}
а для 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)
// err handling and rollback
commitErr := trx.CommitTrx()
Есть ли подобный подход? Как это называется? Я не уверен, подходит ли это шаблон для создания транзакционного запроса.
1 ответ
Думаю, здесь есть несколько моментов.
Шаблон репозитория обычно используется, чтобы скрыть детали реализации хранилища.
Транзакция - это техническая деталь, которую не следует раскрывать на более высоких уровнях.
Другими словами, имеющийся у вас интерфейс репозитория (архитектурный элемент) не должен раскрывать транзакцию (технические детали).
Есть ли подобный подход? Как это называется? Я не уверен, подходит ли это шаблон для создания транзакционного запроса. Возможно, вы захотите узнать больше о шаблоне «Единица работы», который может быть полезен для ваших целей.
Вы можете взглянуть на шаблон «Единица работы».
Ниже приведены некоторые примеры, которые могут вам пригодиться:
- 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