我目前正在我的 .NET 5 REST API 中实现工作单元模式。对于数据库连接,我正在利用我公司提供的一个类,该类配备了用于打开连接和执行查询的方法。目前,所有逻辑和数据库调用都集中在控制器内。为了增强这个结构,我引入了两个额外的层:
为了实现工作单元,我创建了一个继承上述数据库类的类。它具有一个私有字段来存储要执行的查询。当使用 ExecuteSql 函数执行查询时,实际上它会被附加到列表中。当我在工作单元中调用 **SaveChanges ** 方法时,所有查询都会在事务中执行。这是我的工作单元的界面片段:
public interface IMyUnitOfWork : IMyDBConnection
{
List<(string queryStr, object[] parameters)> QueryList { get; set; }
public new void ExecuteSQL(string sql, params object[] parameters);
public void SaveChanges();
}
从 IMyDBConnection 继承的其他方法处理基本的数据库连接和检索查询,因此我不需要更改它。
非常感谢您对我的工作单元实施的见解。鉴于我没有使用任何 ORM,而是仅依赖 SqlConnection 和普通 SQL 查询,这种方法似乎很合适。
我的主要困境是确定将我的工作单元放置在哪里。从逻辑上讲,一个工作单元代表一个离散的“工作单元”,这表明为每个服务打开一个工作单元是合理的。然而,考虑到潜在的循环依赖,人们担心一个服务是否可以调用另一个服务。 如果服务可以互相调用,这些操作是否具有两个不同的数据库上下文,或者它们共享相同的数据库上下文吗?
我正在考虑这两种情况下的潜在问题:
如果我使用相同的数据库上下文,并且由服务 A 调用的服务 B 调用 SaveChanges 方法,它可能会清除查询队列。当我返回服务 A 时,也许我还有其他操作需要排队。此外,如果此时服务 A 中的某些操作失败,我无法回滚已提交的更改。 另一个考虑因素是服务 B 是否需要在执行其他操作之前提交更改。我正在考虑一个场景,我需要向数据库提交一些内容,然后从同一数据库检索数据。虽然在单个服务的范围内是可以管理的,但如果服务调用 SaveChanges 并可能清除本应稍后提交的其他操作,就会变得具有挑战性。
另一方面,如果它们有不同的 DbContext,则意味着如果我调用服务 B 在服务 A 中发布一些数据,之后服务 B 完成但服务 A 中出现异常,我无法回滚该服务B 做到了。
如果一个服务无法调用另一个服务,则不会出现此问题。这是推荐的方法吗?
我正在寻求有关在何处放置我的工作单元的指导,考虑此场景中的最佳实践以及如何处理服务交互以维护一致的数据库上下文。
谢谢!