在存储库模式中,事务边界应该在哪里? [英] Where should the transaction boundary be in a repository pattern?

查看:48
本文介绍了在存储库模式中,事务边界应该在哪里?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个这样的存储库:

I have a repository like so:

public interface IRepository
{
    void Save<T>(T entity);
    void Create<T>(T entity);
    void Update<T>(T entity);
    void Delete<T>(T entity);
    IQueryable<T> GetAll<T>();
}

我的问题是,我的交易边界应该在哪里?我应该在每个方法上打开一个新事务并在返回之前提交它吗?或者它应该围绕整个存储库,以便仅在存储库被处理/垃圾收集时才提交事务?

My question is, where should my transaction boundaries be? Should I open a new transaction on every method and commit it before returning? Or should it be around the entire repository so that the transaction is only committed when the repository is disposed/garbage collected?

推荐答案

工作单元绝对是要走的路.如果您将 SQL Server 与本地数据库一起使用,TransactionScope 将为您完成大部分繁重的工作;只要您在存储库之间共享会话(您是通过构造函数注入进行的,对吧......?),那么您就可以将它们嵌套到您的内心深处.默认情况下,如果有,它就加入环境"事务,如果没有,则启动一个新的事务,这正是您想要的工作单元的行为.

Unit of Work is definitely the way to go. If you're using SQL Server with a local database, TransactionScope will do most of the heavy lifting for you; as long as you share sessions between repositories (which you're doing through constructor injection, right...?), then you can nest these to your heart's content. By default, it enlists in the "ambient" transaction if there is one, and starts a new one if there isn't, which is exactly the behaviour you want for a unit of work.

所以您的存储库可能如下所示:

So your repositories might look like this:

public class UserRepository : IUserRepository
{
    public UserRepository(ISession session)
    {
        this.Session = session;
    }

    public void Save(User user)
    {
        using (TransactionScope tsc = new TransactionScope())
        {
            Session.Save(user);
            tsc.Complete();
        }
    }

    protected ISession Session { get; set; }
}

public class OrderRepository : IOrderRepository
{
    public OrderRepository(ISession session)
    {
        this.Session = session;
    }

    public void Save(Order order)
    {
        using (TransactionScope tsc = new TransactionScope())
        {
            Session.Save(order);
            tsc.Complete();
        }
    }

    protected ISession Session { get; set; }
}

然后您可以像这样执行完整的工作单元:

Then you can perform the complete unit of work like so:

User currentUser = GetCurrentUser();
using (TransactionScope tsc = new TransactionScope())
{
    ISession session = SessionFactory.OpenSession();

    Order order = new Order(...);
    order.User = currentUser;
    IOrderRepository orderRepository = GetOrderRepository(session);
    orderRepository.Save(order);

    currentUser.LastOrderDate = DateTime.Now;
    IUserRepository userRepository = GetUserRepository(session);
    userRepository.Save(currentUser);

    tsc.Complete();
}

如果您不喜欢 TransactionScope 或您的环境阻止您有效地使用它,那么您始终可以实现自己的 UOW 或使用现有的实现.或者,如果您只是一个架构奇才,那么您可以两者兼而有之 - 将通用工作单元接口与主要 DI 库之一结合使用,并使用 TransactionScope 实现您的具体 UOW.

If you don't like TransactionScope or your environment prevents you from using it effectively then you can always implement your own UOW or use an existing implementation. Or if you're just an architectural neat-freak then you can do both - use a generic unit-of-work interface with one of the main DI libraries, and implement your concrete UOW using the TransactionScope.

这篇关于在存储库模式中,事务边界应该在哪里?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆