使用ravendb中的事务存储文档后立即读取文档

时间:2013-04-12 06:58:24

标签: c# transactions ravendb

这里我使用事务范围存储transactionSummary类型的文档,如下所示

public class TransactionSummary
{
[JsonIgnore]
        public Guid? Etag { get; set; }
        public String Id { get; set; }
        public String TransactId { get; set; }
        public OpenOrClosed BalanceType { get; set; }
        public TransactStatus Status { get; set; }
        public String PayeeAccountNo { get; set; }
        public Decimal AmountPaid { get; set; }
}



using (var trans = new TransactionScope())
{
  using (IDocumentSession sess = GetConnection())
   {
     sess.Store(fldtrans);
     sess.SaveChanges();
   }
    trans.complete();
}

立即存储后我需要检索它,所以我按照以下方式进行操作

   using (IDocumentSession sess = GetConnection())
   {
     sess.Advanced.AllowNonAuthoritativeInformation = false;
     sess.Advanced.UseOptimisticConcurrency = true;
     transact = sess.Query<TransactionSummary>().Where(x => x.TransactId ==transactid).FirstOrDefault();                                                                 
     transact.Etag = sess.Advanced.GetEtagFor(transact);
   }

这里我得到如下例外情况    ex = {“Value不能为null。\ r \ nParameter name:key”} StackTrace =“
at System.Collections.Generic.Dictionary 2.FindEntry(TKey key)\r\n at System.Collections.Generic.Dictionary 2.TryGetValue(TKey key,TValue&amp; value)\ r \ n在raven.Client.Document.InMemoryDocumentSessionOperations.GetDocumentMetadata [T](T实例)中...

据我所知,提交事务需要一定的时间,因此当文档立即被读取时会失败。但我怎样才能克服这一点,以免我牺牲自己的要求。

马特在这里,我正在做很多其他工作,在那个交易范围我刚刚看到了你的一瞥,了解其中一个是我将TransactionId发布到队列而我的后台服务获取transactionId(不是文档Id)并且在事务发生后需要完成其他一些过程。这就是在真实数据库中事务受到影响之前,队列先获取transactionId。

这是我的Getconnection代码供参考。

public class DataAccess : IDataAccess
    {
        static IDocumentStore _docStore ;
        public DataAccess()
        {

            _docStore = new DocumentStore { Url = "http://localhost:8081" };
            _docStore.Initialize();
            _docStore.Conventions.IdentityPartsSeparator = "-";  

        }

        #region IDataAccess Members

        public IDocumentSession GetConnection()
        {

            IDocumentSession sess = _docStore.OpenSession();
            _docStore.DatabaseCommands.EnsureDatabaseExists("MyDB");
            return sess=_docStore.OpenSession("MyDB");
        }

1 个答案:

答案 0 :(得分:5)

根据您所显示的内容,无需明确定义事务范围。围绕由会话范围定义的工作单元已存在隐式事务。您应该明确使用TransactionScope的唯一时间是,如果您使用不同的会话调用两个或更多个单独的数据库 - 或者调用raven和其他一些事务感知过程。

我不确定您为什么要在存储后立即在新会话中查询。你肯定会有陈旧的索引问题需要解决。如果你真的必须这样做,你应该只是通过Id

加载文档

也许您没有意识到这一点,但在第一次会话中调用Id后,.Store()即可立即使用 - 甚至在您保存更改之前。如果您想获取文档的etag,可以在第一个会话中.GetEtagFor()电话后立即拨打.SaveChanges()。实际上没有必要为这两个目的创建另一个会话。

如果您还没有,那么您还应该阅读有关乐观并发和etag问题的this RavenDB KB article。我想你会发现你在那里解决的大部分问题。

最后一件事 - 请更新您的问题以显示GetConnection()方法的代码。如果不正确使用IDocumentSessionIDocumentStore,则很难判断。感谢。