【问题标题】:db4o Client See Changes from Another Clientdb4o 客户端查看来自另一个客户端的更改
【发布时间】:2011-12-09 23:35:41
【问题描述】:

我正在运行一个有多个客户端访问它的 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,而是为每个 DB 请求打开一个新的 IObjectContainer。

对吗?

是的,#1 更有效,但是指定刷新哪些对象真的很现实吗?我的意思是,当涉及数据库时,每次客户端访问它时,它都应该获得最新信息。这就是为什么我倾向于#2。另外,我没有主要的效率问题。

那么,我说这两种方法对吗?或者还有别的吗?

还有,等一下……当你的对象超出范围时会发生什么?在计时器上,我调用了一个从数据库服务器获取对象的方法。该方法实例化对象。由于对象超出范围,因此无法刷新。当我打电话给数据库时,我看不到客户端的变化。在这种情况下,似乎唯一的选择是打开一个新的 IObjectContainer。没有?

** 编辑 **

我想我会使用我最终决定使用的解决方案发布一些代码。由于每次调用都使用新的 IObjectContainer 存在一些严重的复杂性,因此我将在每个访问数据库的方法中执行 Refresh()(请参阅下面的 Refresh() 行)。由于我已将数据库访问封装到逻辑类中,因此我可以确保每次都在那里执行 Refresh()。我刚刚对此进行了测试,它似乎可以正常工作。

注意:下面的数据库变量是 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;
}

【问题讨论】:

    标签: db4o


    【解决方案1】:

    1)正如您所说,您通常真的不知道要刷新哪些对象的主要问题。 一旦任何客户端提交,您就可以使用 committed event 刷新对象。 db4o 将分发该事件。请注意,这也会消耗一些网络流量和时间来发送事件。并且会有一个时间范围,您的对象会处于陈旧状态。

    2) 它实际上是最干净的方法,但不是针对每个数据库请求。为每个逻辑工作单元使用一个对象容器。在您的业务运营中作为一个“原子”工作单元的任何操作。

    总的来说。 db4o 从来没有以客户端服务器场景为第一优先级来构建,它显示在并发场景中。您无法避免使用陈旧(甚至不一致)的对象状态,并且没有并发控制选项(除了低级信号量)。

    我的建议:每个工作单元使用一个客户端容器。请注意,即使那样,您也可能会获得陈旧的数据,这可能会导致视图和更新不一致。当您的应用程序场景中很少有任何争用和竞争并且您可以偶尔容忍错误时,这很好。但是,如果您确实需要确保正确性,那么我建议使用具有更好并发存储的数据库 =(

    【讨论】:

    • 谢谢,Gamlor。在 db4o 上投入了这么多时间之后,这很难接受:“……你可以容忍偶尔出现一次错误……” 如果出现错误,怎么可能考虑使用 DB?我已经创建了一个 db4o 服务器,以及两个使用它的不同应用程序。不知道现在该怎么办。乌鸦数据库?还有什么?
    • 你真的需要100%绝对正确吗?大多数应用程序不需要它(金融应用程序需要它)。那么上面的选项可能“足够好”。但如前所述,这实际上取决于应用程序。当然,您可以使用 db4o 解决这些问题,但它会变得非常快,非常难。致 RavenDB:RavenDB 无疑是一个非常棒的文档数据库。请注意,默认情况下 RavenDB 还允许返回状态结果。但它更容易控制陈旧性并且它具有乐观锁定支持。
    • 我会说没有 100% 的正确性可能是灾难性的。我正在创建一个自动部署应用程序。如果用户更改了应用服务器应该使用的连接字符串,而应用服务器在更新自己时看不到该更改,那就不好了。
    • 选项 2 有一些复杂性。如果我们使用一个 IObjectContainer 来检索一个对象,然后使用另一个 IObjectContainer 来保存它,那是行不通的。新的 IObjectContainer 将向 DB 添加一个新对象,而不是保存现有对象。是时候尝试思考一个优雅的解决方案了……
    • @Update 场景:我认为这是一个典型的场景,您可以接受一些暂时的不一致。当然,它应该很少发生,并且能够从暂时的不一致中恢复。但是你当然需要一些刷新状态,比如上面展示的回调机制。
    猜你喜欢
    • 2018-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-09
    相关资源
    最近更新 更多