Комментарии 6
В итоге остановился на такой реализации:
// pkg/uow.go
package uow
type UoW[T any] interface {
InTx(ctx context.Context, f func(ctx context.Context, tx T))
}// handler.go
package handler
import (
"model"
"context"
"pkg/uow"
)
type UsersRepository interface {
Save(ctx context.Context, user model.User)
}
type OrdersRepository interface {
Save(ctx context.Context, order model.Order)
}
type tx interface {
GetUsersRepo() UsersRepository
GetOrdersRepo() OrdersRepository
}
type Handler struct {
users UsersRepository
orders OrdersRepository
uow uow.UoW[tx]
}
func (h *Handler) Handle(ctx context.Context) {
h.uow.InTx(ctx, func(ctx context.Context, tx tx) {
u := tx.GetUsersRepo()
o := tx.GetOrdersRepo()
})
}Я делаю каждую CRUD операцию по 2 раза, без передачи транзакции и с передачей. (первая вызывает вторую) Кому не надо знать про БД вызывают первую функцию, а кому хочется трнзакцию вызывают вторую функцию :-)
// Read - находит запись в БД по ID
func (crud Crud_DB) Read(m *banks.Bank) error { }
// Read_ctx - находит запись в БД по ID
func Read_ctx(ctx context.Context, db postgres_pgx.IConnectionTransaction, m *banks.Bank) error { }
Я для себя решил использовать интерфейс типа QueryExecutor который реализует два объекта - один является оберткой над хэндлером БД, второй - над хэндлером транзакции. Обычно, этого хватало для гибкости.
А можно пример посмотреть?
Порылся в своих проектах и что-то не могу найти эту библиотечку. К сожалению, я ее больше использовал в приватных проектах.
Попробовал восстановить примерно то, что было через иишку - https://drive.google.com/file/d/1qllUL6utlIIajmaxKYrq7kGLLKGanRWX/view?usp=sharing
В итоге остановился на такой реализации:
// pkg/uow.go
package uow
type UoW[T any] interface {
InTx(ctx context.Context, f func(ctx context.Context, tx T))
}// handler.go
package handler
import (
"model"
"context"
"pkg/uow"
)
type UsersRepository interface {
Save(ctx context.Context, user model.User)
}
type OrdersRepository interface {
Save(ctx context.Context, order model.Order)
}
type tx interface {
GetUsersRepo() UsersRepository
GetOrdersRepo() OrdersRepository
}
type Handler struct {
users UsersRepository
orders OrdersRepository
uow uow.UoW[tx]
}
func (h *Handler) Handle(ctx context.Context) {
h.uow.InTx(ctx, func(ctx context.Context, tx tx) {
u := tx.GetUsersRepo()
o := tx.GetOrdersRepo()
})
}
Все (я надеюсь) способы работать с транзакциями в go