我正在运行一个有多个客户端访问它的db4o服务器。我刚遇到一个客户端没有看到来自另一个客户端的更改的问题。根据我在网络上的研究,看起来基本上有两种方法可以解决它。
1:在对象上调用Refresh()(来自http://www.gamlor.info/wordpress/2009/11/db4o-client-server-and-concurrency/):
const int activationDeph = 4;
client2.Ext()。Refresh(objFromClient2,activationDeph);
2:不是缓存IObjectContainer,而是为每个数据库请求打开一个新的IObjectContainer。
是吗?
是的,#1效率更高,但指定要刷新哪些对象真的很现实吗?我的意思是,当涉及到数据库时,每次客户端访问它时,都应该获取最新信息。这就是为什么我倾向于#2。另外,我没有主要的效率问题。
那么,我是对的,这两种方法是什么?或者还有另一个吗?
然后,等一下......当你的物体超出范围时会发生什么?在计时器上,我调用一个从数据库服务器获取对象的方法。该方法实例化对象。由于对象超出范围,因此无法刷新。当我调用数据库时,我看不到客户端的更改。在这种情况下,似乎唯一的选择是打开一个新的IObjectContainer。否?
**编辑**
我以为我会使用我最终决定使用的解决方案发布一些代码。由于每次调用使用新的IObjectContainer都有一些严重的复杂性,我只想在访问数据库的每个方法中执行Refresh()(参见下面的Refresh()行)。由于我已将数据库访问封装到逻辑类中,因此每次都可以确保在那里执行Refresh()。我刚刚测试了它,它似乎正在工作。
注意:下面的Database变量是db4o IObjectContainer。
public static ApplicationServer GetByName(string serverName)
{
ApplicationServer appServer = (from ApplicationServer server in Database
where server.Name.ToUpperInvariant() == serverName.ToUpperInvariant()
select server).FirstOrDefault();
Database.Ext().Refresh(appServer, 10);
return appServer;
}
答案 0 :(得分:2)
1)正如你所说,这个主要问题是你通常真的不知道要刷新什么对象。 任何客户端提交后,您都可以使用c ommitted event刷新对象。 db4o将分发该事件。请注意,这也消耗了一些网络流量和发送活动的时间。并且会有一个时间框架,您的对象处于陈旧状态。
2)它实际上是最干净的方法,但不适用于每个db请求。为每个逻辑工作单元使用对象容器。任何操作,这是您业务运营中的一个“原子”工作单元。
总的来说。 db4o永远不会以客户端服务器方案作为第一优先级构建,并且它在并发方案中显示。您无法避免使用陈旧(甚至不一致)的对象状态,并且没有并发控制选项(低级信号量除外)。
我的建议:每个工作单元使用一个客户端容器。请注意,即使这样,您也可能会收到过时的数据,这可能会导致视图不一致。更新。当很少有任何争论时你的应用场景中的比赛,你可以偶尔容忍一个错误,那么这很好。但是,如果您确实需要确保正确性,那么我建议使用具有更好的并发存储的数据库=(