【问题标题】:Application architecture - Transactions w/ RavenDB应用程序架构 - 带有 RavenDB 的事务
【发布时间】:2011-10-10 14:16:44
【问题描述】:

我正在一个项目中实现 RavenDB,在尝试了几天后,我正在构建这个应用程序,但我有一个问题。

我正在为每个实体(几乎)编写业务层,并且我有一个独特的存储库类来处理查询和 DocumentStore。 我对如何沿着服务层共享 DocumentStore 并处理事务感到困惑。

我正在展示一个示例,我尝试在单个事务中存储和读取文档。

存储库示例:

public class RavenRepository
{
    private static DocumentStore _store;
    private IDocumentSession _session;

    public RavenRepository(DocumentStore store)
    {
        _store = (_store==null) ? new DocumentStore() { Url = "http://wsk-gcardoso:8081" } : store;           
    }
    public T SingleOrDefault<T>(Func<T, bool> predicate) where T : BaseModel
    {
        using (var session = _store.OpenSession())
        {
            return session.Query<T>().SingleOrDefault(predicate);
        }
    }
    public T Add<T>(T item) where T : BaseModel
    {            
        using (var session = _store.OpenSession())
        {
            session.Advanced.AllowNonAuthoritiveInformation = this.AllowNonAuthoritiveInformation;
            session.Store(item);
            session.SaveChanges();
        }
        return item;
    }
    public void Initialize() {
        _store.Initialize();
    }
    public void Dispose() {
        _store.Dispose();
    }
}

一个业务层应该是这样的:

public class NewsletterBusiness
{
    private RavenRepository repository;
    public NewsletterBusiness(RavenRepository ravenRepository)
    {       
        repository = (ravenRepository == null) ? RavenRepository(null) : ravenRepository;
    }

    public Newsletter Add(Newsletter newsletter)
    {
        Newsletter news = repository.Add(newsletter);
        return news;
    }
    public Newsletter GetById(long Id)
    {
        Newsletter news = repository.SingleOrDefault<Newsletter>(x => x.Id == Id);
        return news;
    }
}

现在我正在尝试在同一个事务中保存和读取一个对象(通讯)。 根据我的阅读,我必须将 documentStore 的 AllowNonAuthoritativeInformation 设置为 false 才能等到事务完成。但是从我处理层和存储库的方式来看,我是否在单个事务中存储和查询数据库?

说实话,我认为我对存储的 OpenSession 方法感到困惑。我想我将会话与事务混淆了。

例如这段代码:

var repository = new RavenRepository(null);
newsletterBusiness = new NewsletterBusiness(repository);
repository.Initialize();
using (var tx = new TransactionScope())
{
    Newsletter new = newsletterBusiness.Add(new Newsletter { Title = "Created by Tests", Content = "Created By Tests" });

    Newsletter objectCreated = newsletterBusiness.GetById(new.Id);
    repository.Dispose();
    tx.Complete();
}

如果我创建第二个业务层(例如图片)并设置 picturesBusiness.repository = repository(为 businessLayer 设置相同的“RavenRepository 对象),我将在相同的环境中工作newsletterBusiness.repository 的会话?

picturesBusiness = new PicturesBusiness(repository);
Picture pic = picturesBusiness.GetById(20);

我非常感谢有关此主题的帮助, 来自葡萄牙的干杯!

【问题讨论】:

    标签: repository-pattern ravendb n-tier-architecture


    【解决方案1】:

    您没有正确使用 RavenDB,这就是您遇到此问题的原因。 您可以将会话视为数据库连接。在您的模型中,您正在为每种类型创建一个单独的会话。但是你真的没有真正的理由要这样做。

    事实上,您想要这样做,因为会话完全能够同时处理多种类型。 此外,您所做的实际上是减少了会话机会,以优化诸如将一批更新发送到服务器之类的事情。

    如果您想要一个跨类型的事务性写入,那么根据您的架构,您将不得不使用 DTC,因为每个不同的会话都是与数据库的不同连接。如果您使用 Session per Request 模型,那么您将只有一个会话,并且只需调用 SaveChanges() 一次即可获得事务语义。

    【讨论】:

      【解决方案2】:

      您正在尝试通过存储库模式抽象 raven 的会话(基本上是 UnitOfWork)。

      我建议您采用以下方法 - 创建一个 UnitOfWork 抽象,它将封装 ravenDB 会话并从中实例化存储库。这是一些伪代码:

      public class RavenUnitOfWork {
          private IDocumentSession m_session;
      
          public UnitOfWork() {
              // initialize m_session here
          }
      
          public Repository<T> GetRepository() {
              return new Repository<T>(m_session);
          }
      
          public void Commit() {
              m_session.SaveChanges();
          }
      }
      
      public class RavenRepository<T> {
          public Repository(IDocumentSession session) {
              // Store the session
          }
          public T Load(string id) {...}
          public void Store(T entity) {...}
          public void Delete(T entity) {...}
          public IQueryable<T> Query() {...}
      }
      

      在这里你明确地实现了这些模式。

      P.S.:当然你可以根据自己的喜好声明 IUnitOfWork 和 IRepository...

      【讨论】:

        猜你喜欢
        • 2011-11-29
        • 1970-01-01
        • 2021-05-19
        • 1970-01-01
        • 1970-01-01
        • 2012-02-21
        • 1970-01-01
        • 2013-09-17
        • 1970-01-01
        相关资源
        最近更新 更多