db4o到db4o复制不完全复制

时间:2014-03-04 02:39:53

标签: java database-replication db4o

我无法让复制在两个db4o数据库之间完全运行。我已经遵循了许多教程,我的代码似乎与它们相同(显然不是这样)。输出表明ReplicationSession正在检测更改,但它不会复制其他数据库中的更改。

private ReflectiveDatabase()
{
    openDb();
    providerA = new Db4oEmbeddedReplicationProvider(hostContainer);
    providerB = new Db4oEmbeddedReplicationProvider(clientContainer);

    //Start a new ReplicationSession with event for replacing newest object on conflict.
    replication = Replication.begin(providerA, providerB,
    new ReplicationEventListener() {
        @Override
        public  void onReplicate(ReplicationEvent replicationEvent) {
            if (replicationEvent.isConflict()) {
                ObjectState stateDesktop = replicationEvent.stateInProviderA();
                ObjectState stateMobile = replicationEvent.stateInProviderB();

                if (stateDesktop.modificationDate() >= stateMobile.modificationDate()) {
                    replicationEvent.overrideWith(stateDesktop);
                } else {
                    replicationEvent.overrideWith(stateMobile);
                }
            }
        }
    });   
}

public EmbeddedConfiguration configure()
{
    EmbeddedConfiguration configuration = Db4oEmbedded.newConfiguration();
    configuration.file().generateUUIDs(ConfigScope.GLOBALLY);
    configuration.file().generateCommitTimestamps(true);
    return configuration;
}

public void openDb()
{
    // try to connect to the host
    if(hostContainer != null) hostContainer.close();

    try
    {
        hostContainer = Db4oEmbedded.openFile(configure(), "local1.db4o");
    }
    catch (com.db4o.ext.Db4oIOException e)
    {
        ...
    }

    // try to connect to the client
    if(clientContainer != null) 
    {
        clientContainer.close();
    }

    try
    {
        clientContainer = Db4oEmbedded.openFile(configure(), "local2.db4o");
    }
    catch (com.db4o.ext.Db4oIOException e)
    {
        ...
    }
}

这是我每8秒从计时器运行的实际同步

public void syncDatabases()
{        
    // First get the changes of the two replication-partners
    ObjectSet<Object> changesOnHost = replication.providerA().objectsChangedSinceLastReplication();
    ObjectSet<Object> changesOnClient = replication.providerB().objectsChangedSinceLastReplication();
    System.out.println("Changes on Server: " + changesOnHost.size());
    System.out.println("Changes on Client: " + changesOnClient.size());
    // then iterate over both change-sets and replicate it
    for (Object changedObjectOnClient : changesOnClient)
    {
        replication.replicate(changedObjectOnClient);
    }
    for (Object changedObjectOnHost : changesOnHost)
    {
        replication.replicate(changedObjectOnHost);
    }
    replication.commit();
}

public void writeToClient(Object object)
{
    clientContainer.store(object);
    clientContainer.commit();
}

适用于创建和写入数据库的新对象。

如果我从其中一个数据库中编写一个更改过的对象(例如字段更改),则运行时的同步方法将检测到存在已更改的对象,实际上它是正确的并且其字段已更改。但是,我没有看到该对象在其他数据库中被复制。它的字段与更改的对象字段不同。

我是否只是对db4o的复制能力存在误解?这有点超出了我的联赛第二年,但如果有人能看到我出错的地方,我将非常感激。

1 个答案:

答案 0 :(得分:0)

我设法让版本8正确复制。我没有完全遵循教程并做出假设(虽然没有澄清它仍然是一个假设)。

似乎在同步时实例化ReplicationSession和ReplicationProviders至关重要。我更改了我的代码,以便在SyncDatabases()中创建并保存这些代码(我猜垃圾收集会处理它们)。

public void syncDatabases()
{        
    // First get the changes of the two replication-partners
    Db4oEmbeddedReplicationProvider providerA = new Db4oEmbeddedReplicationProvider(hostContainer);
    Db4oEmbeddedReplicationProvider providerB = new Db4oEmbeddedReplicationProvider(clientContainer);
    ReplicationSession replication = Replication.begin(providerA, providerB);

    ObjectSet<Object> changesOnHost = replication.providerA().objectsChangedSinceLastReplication();
    ObjectSet<Object> changesOnClient = replication.providerB().objectsChangedSinceLastReplication();

    // then iterate over both change-sets and replicate it
    for (Object changedObjectOnClient : changesOnClient)
    {
        replication.replicate(changedObjectOnClient);
    }
    for (Object changedObjectOnHost : changesOnHost)
    {
        replication.replicate(changedObjectOnHost);
    }
    replication.commit();

    replication.replicateDeletions(Object.class);
}

构造函数只是运行openDb()来初始化objectContainers。