【问题标题】:Transactions in the Repository Pattern using ServiceStack.ORMLite使用 ServiceStack.ORMLite 的存储库模式中的事务
【发布时间】:2013-02-04 23:27:15
【问题描述】:

我正在使用 ServiceStack.ORMLite 实现存储库模式,如下所示:

public class MyRepository : IMyRepository
{
    private IDbConnectionFactory DbConnectionFactory = null;

    public MyRepository(IDbConnectionFactory dbConnectionFactory)
    {
        DbConnectionFactory = dbConnectionFactory;
    }

    public void MyMethod()
    {
        using (var connection = DbConnectionFactory.OpenDbConnection())
        using (var cmd = connection.CreateCommand())
        {
            //Do something here
        }
    }
}

但是当我需要在 DbTransaction 中扭曲一些 DB 操作时,我不知道如何处理 DbTransaction。看起来TransactionScope 是一个解决方案,但我不知道这是否过于繁重。

【问题讨论】:

    标签: repository-pattern servicestack ormlite-servicestack


    【解决方案1】:

    ServiceStack OrmLite 让您可以访问 ADO.NET 的原始 IDbConnectionIDbTransaction 类,您应该使用它们来代替 TransactionScope 的。您可以使用IDbConnection.OpenTransaction()扩展方法创建事务,例如:

    public class MyRepository : IMyRepository, IDisposable
    {
        private IDbConnectionFactory DbFactory { get; set; }
    
        private IDbConnection db;
        private IDbConnection Db
        {
            get { return db ?? (db = dbFactory.Open()); }
        }
    
        public void WithTransactions()
        {
            using (var trans = Db.OpenTransaction())
            {
                //Do something here
    
                trans.Commit();
            }
        }
    
        public List<Poco> WithoutTransactions()
        {
            return Db.Select<Poco>();
        }
    
        public void Dispose()
        {
            if (db != null) 
                db.Dispose();
        }
    }
    

    由于它需要更少的代码,我更喜欢属性注入并使用 Lazy Db 属性来简化我的方法的数据访问模式。

    注意:每当您的任何类保留对打开的 IDbConnection 的引用(例如这个)时,它都应该使用 None/TransientRequestScope 进行注册因此连接在使用后被释放(即不要将其注册为单例)。

    【讨论】:

    • 每个请求只打开一次 IDbConnection 并在使用后处理好?我认为我应该在每个方法开始时打开连接并在方法结束时关闭它。
    • 没关系,如果您使用连接池(即 SqlServer 的默认行为),连接并没有真正关闭,它只是释放回池中。但是,无论哪种方式都可以使用 Request Scope,因为它是每个请求的单线程,因此可以安全地与同一请求范围内的其他依赖项共享连接实例。
    • 如果一个请求长时间保持连接,但它只需要访问DB只是一个monent(比如为DB选择一些数据然后处理它),我认为DB的性能会不好...但是手动处理连接并不容易...
    • 你没有正当理由这么想。如果长时间运行的连接需要多次访问数据库,你会怎么做?在同一个请求中多次重新打开数据库连接?打开新连接比重新使用现有连接更好吗?看来你不了解连接池或者多线程,不要想太多,答案是使用 Transient 或者 RequestScope。但是,如果您是偏执狂,请随时像您在示例中所做的那样,每次都明确地打开和关闭连接。
    • 我想我可能误解了 IDbTransaction IDbCommand 和 IDbConnection 之间的关系...我同意你的说法...
    【解决方案2】:

    我喜欢 mythz 的回答,但根据 mythz 的反馈,我自己在让事情按预期工作时遇到了一些麻烦。我遇到了另一个答案,起初,它似乎不是我想要的,但最终让我朝着正确的方向前进。

    Best practices of implementing unit of work and repository pattern using ServiceStack.ORMLite

    【讨论】:

      猜你喜欢
      • 2010-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多