wcl*_*wcl 4 database domain-driven-design transactions go go-gorm
我们知道服务(控制器/用例)层是处理业务逻辑,repo 是处理数据库查询
现在我有:
func (s *OrderService) Create(order models.Order) (models.Order, error) {
...
user := models.User{
Contact: order.Address.Contact,
}
createdUser, err := s.UserRepo.Save(user)
// err handling...
order.User = user
createdOrder, err := s.OrderRepo.save(order)
// err handling...
return order, nil
}
Run Code Online (Sandbox Code Playgroud)
// user_repo.go
func (repo *UserRepo) Save(user models.User) (models.User, error) {
err := repo.DB.Debug().Save(&user).Error
// err handing...
return user, nil
}
// order_repo.go
func (repo *OrderRepo) Save(order models.Order) (models.Order, error) {
err := repo.DB.Debug().Save(&order).Error
// err handing...
return order, nil
}
Run Code Online (Sandbox Code Playgroud)
我希望应用 gormdb.Begin()
事务变得更加灵活,而不是我当前的代码过于静态。那么我应该删除 gorm.DB 存储库但是
我。通过params传入gorm.DB?
tx := s.DB.Begin()
createdUser, err := s.UserRepo.Save(user, tx)
Run Code Online (Sandbox Code Playgroud)
二. 或者直接在服务层运行查询?(但是它打破了ddd的设计理念)
tx := s.DB.Begin()
createdUser, err := tx.Create(&user)
if err != nil {
tx.Rollback()
}
createdOrder, err := tx.Create(&order)
if err != nil {
tx.Rollback()
}
tx.Commit()
Run Code Online (Sandbox Code Playgroud)
小智 6
根据 DDD,事务不应跨越聚合边界。
参考:
如果我们出于某种原因需要在事务中更新它们,您可能需要重新考虑它们是否应该成为某些聚合的一部分
在编写聚合存储库时,可以巧妙地将事务隐藏在存储库层中
我一般都是按照下面的界面
// holds the business logic to modify the aggregate, provided by business layer
type AggregateUpdateFunction func (a *Aggregate) error
type Repository interface {
Create(ctx context.Context, aggregate *Aggregate)
Read(ctx context.Context, id string) *Aggregate
// starts a read-modify-write cycle internally in a transaction
Update(ctx context.Context, id string, updateFunc AggregateUpdateFunction) error
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3816 次 |
最近记录: |