gpt4 book ai didi

database - DDD 设计模式建议中的交易

转载 作者:行者123 更新时间:2023-12-03 10:07:21 25 4
gpt4 key购买 nike

我们知道服务(controller/usecase)层是处理业务逻辑的,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
}
// 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
}

我希望应用 gorm db.Begin() 事务变得更加灵活,而不是我当前的代码过于静态。所以我应该删除 gorm.DB 存储库但是

我。通过参数传入 gorm.DB??

tx := s.DB.Begin()
createdUser, err := s.UserRepo.Save(user, tx)

二。还是直接在服务层运行查询?? (但它打破了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()

最佳答案

根据 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
}

关于database - DDD 设计模式建议中的交易,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65573939/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com