服务层 - 数据库事务

时间:2014-07-21 23:36:51

标签: c# asp.net-mvc entity-framework

我正在开发一个具有服务层和数据访问层的MVC-EF应用程序。控制器与服务层交互,并且服务层又与数据访问层交互。数据访问层基于存储库模式的简单实现,大多数时候都会暴露crud操作。

我在服务层方法中使用事务:

bool done = false;
using (IDatabaseTransaction transaction = this.businessDataSource.BeginTransaction())
{
    try
    {
        // Execute some statements updating database
        // ....

        transaction.Commit();

        done = true;
    }
    catch (Exception)
    {
        transaction.Rollback();
    }
}

return done;

其中BeginTransaction是存储库基类的方法:

    public IDatabaseTransaction BeginTransaction()
    {
        return new DatabaseTransaction(this.Context.Database.BeginTransaction());
    }

实施的服务方法,例如, EmployeeService,就像AddEmployee(Employee emp),AssignEmployeeToDepartments(int empId,IList departmentNames),它们的语句包含在上面的using(IDatabaseTransaction事务)语句中,假设方法复杂,具有复杂的业务逻辑(比起名字:))。

现在我必须实施第三种方法,例如比如ImportEmployee(),它是先前实现的方法AddEmployee()和之前实现的AssignEmployeeToDepartments()的聚合方法。回顾早期实现的方法很复杂,因此需要重复使用。

所以我的问题是:

如何重构(或以特定方式实现)这些服务方法,因此它们可以单独使用,也可以作为另一种服务方法的一部分使用(也可以在事务中执行其语句)?

TIA。

修改

我花了一些时间阅读stackoverflow和其他地方的相关帖子,并且几乎没有想法如何解决问题。我在下面描述了一个看起来很有希望的那个。

解决方案的关键是" HttpContext.Items" (可通过HttpContext.Current.Items获得),根据定义,它是按请求缓存。 由于我的所有事务处理都在服务方法中,每当我需要在服务方法中启动一个新事务时,我会在HttpContext.Items中添加一个标志:

    if (!HttpContext.Current.Items.Contains("HasActiveTranaction"))
        HttpContext.Current.Items.Add("HasActiveTranaction", true);

检查是否尚未启动任何交易。如果密钥HasActiveTranaction存在,那么这意味着它已经作为另一个事务的一部分执行,并且在这种情况下不会创建事务。此外,在尝试提交或回滚事务之前执行相同的检查。

这样就可以使用另一种服务方法,也可以自己使用(拥有自己的事务)。

可以通过使用属性" HasActiveTranaction"创建静态类型TransactionHelper来进一步改进。首先,集中访问它。

这听起来不错吗?

0 个答案:

没有答案