我正在运行我的应用程序的两个实例。在一个例子中,我保存了我的一个实体。当我检查RavenDB(http:// localhost:8080 / raven)时,我可以看到更改。然后,在我的其他客户端,我这样做(下面),但我没有看到来自其他应用程序的更改。为了获取数据库中的最新数据,我需要做什么?
public IEnumerable<CustomVariableGroup> GetAll()
{
return Session
.Query<CustomVariableGroup>()
.Customize(x => x.WaitForNonStaleResults());
}
编辑:如果我尝试进行更改并获得并发异常,则上述代码有效。之后,当我调用refresh(调用上面的代码)时,它会起作用。
以下是执行保存的代码:
public void Save<T>(T objectToSave)
{
Guid eTag = (Guid)Session.Advanced.GetEtagFor(objectToSave);
Session.Store(objectToSave, eTag);
Session.SaveChanges();
}
这是包含数据库和会话的类:
public abstract class DataAccessLayerBase
{
/// <summary>
/// Gets the database.
/// </summary>
protected static DocumentStore Database { get; private set; }
/// <summary>
/// Gets the session.
/// </summary>
protected static IDocumentSession Session { get; private set; }
static DataAccessLayerBase()
{
if (Database != null) { return; }
Database = GetDatabase();
Session = GetSession();
}
private static DocumentStore GetDatabase()
{
string databaseUrl = ConfigurationManager.AppSettings["databaseUrl"];
DocumentStore documentStore = new DocumentStore();
try
{
//documentStore.ConnectionStringName = "RavenDb"; // See app.config for why this is commented.
documentStore.Url = databaseUrl;
documentStore.Initialize();
}
catch
{
documentStore.Dispose();
throw;
}
return documentStore;
}
private static IDocumentSession GetSession()
{
IDocumentSession session = Database.OpenSession();
session.Advanced.UseOptimisticConcurrency = true;
return session;
}
}
答案 0 :(得分:4)
缺乏更详细的信息和一些代码,我只能猜测......
请确保在会话中致电.SaveChanges()
。如果没有明确指定ITransaction,您的IDocumentSession将被隔离并在它打开和调用.SaveChanges
之间进行事务处理。所有操作都成功或无成功。但是如果你不打电话,你之前的所有.Store
电话都会丢失。
如果我错了,请发布有关您的代码的更多详细信息。
编辑:第二个答案(在补充信息之后):
您的问题与RavenDB在客户端缓存的方式有关。默认情况下,RavenDB会在DocumentSession中缓存每个GET请求。普通查询只是GET查询(不,它与您的索引在动态或手动定义的前期无关),因此它们将被缓存。您的应用程序中的解决方案是处置会话并打开一个新会话。
我建议您重新考虑会话生命周期。您的会话似乎过得太长,否则这种并发性不会成为问题。如果您正在构建网络应用程序,我建议您在请求开始和结束时打开和关闭会话。看看RaccoonBlog,看看它是否优雅地实现了。
答案 1 :(得分:2)
鲍勃, 看起来你在应用程序中只有一个会话,这是不对的。以下文章讨论了NHibernate,但会话管理部分也适用于RavenDB:
http://archive.msdn.microsoft.com/mag200912NHibernate
这段代码毫无意义:
Guid eTag = (Guid)Session.Advanced.GetEtagFor(objectToSave);
Session.Store(objectToSave, eTag);
它基本上是一个没有操作,但看起来很重要。您似乎正在尝试使用模型,您必须手动管理所有保存,不要这样做。您只需在创建新项目时自己管理事物,就是这样。
至于你遇到这个问题的原因,这里有一个例子:
var session = documentStore.OpenSession();
var post1 = session.Load<Post>(1);
// change the post by another client
post2 = session.Load<Post>(1); // will NOT go to the server, will give the same instance as post1
Assert.ReferenceEquals(post1,post2);
会话是短暂的,通常在单个表单/请求的范围内使用。