db4o open source object database
db4o :: Product News Blog

Syndicate This

Thursday, May 12, 2005

db4o 4.5 released

Our new 4.5 production release is an important milestone:

  • We added new bidirectional replication functionality to allow syncronizing multiple databases. Although the feature was written with disconnected client databases in mind, we already have users telling us that they are experimenting to use it for distributed databases on the server side, to implement load balancing between multiple servers.

  • "ObjectManager" is a new GUI tool to browse and query databases. It is available as a separate download from the
    db4o downloadcenter website
    .

  • Our new reflector architecture is released. Principally it should allow running a db4o server without having to deploy application classes. For now we still recommend deploying all application classes to the server since we feel that the "generic reflector" functionality is not stable enough for production use yet.

  • We have added another IoAdapter implementation to the db4o distribution:
    com.db4o.io.MemoryIoAdapter
    It allows running any db4o configuration (local database and server) in-memory.
    The new adapter will deprecate the old ExtDb4o.openMemoryFile() functionality.

  • This is the first production release built with our completely new Java => C# converter. The C# source code now finally is just as readable as the Java source code, it is exactly the same.

Let's take a look at the new replication functionality in detail.

In order to use replication, the following configuration calls are necessary, to tell db4o to generate version numbers and unique universal IDs for all objects:
Db4o.configure().generateUUIDs(Integer.MAX_VALUE);
Db4o.configure().generateVersionNumbers(Integer.MAX_VALUE);

The above calls should be issued before opening a database file the first time, but you can also add version numbers and UUIDs at a later stage by defragmenting a database file with the above settings in place.

Now suppose we want to replicate objects between two open ObjectContainers (databases), "server" and "handheld", this is how we connect them for replication:

ReplicationProcess replicationProcess =
server.ext().replicationBegin(
handheld,
new ReplicationConflictHandler() {
public Object resolveConflict(
ReplicationProcess replicationProcess,
Object a,
Object b) {

// here we return the object that we want to prevail,
// in case it has been modified in both ObjectContainers
// or null, if this object should not be replicated if
// a conflict occurs

return a;

}
}
);

Now we can simply query either of the two connected ObjectContainers for objects and
pass them to the replicationProcess to be replicated. In case the two ObjectContainers have been synchronized before, we can constrain the query, only to return objects that were modified since the last replication:

Query q = server.query();
replicationProcess.whereModified(q);
ObjectSet replicationSet = q.execute();
while (replicationSet.hasNext()) {
replicationProcess.replicate(replicationSet.next());
}
replicationProcess.commit();

Basically this is all that is necessary to get replication running in production. When objects are replicated, their children will be traversed as long as objects are found that are either unknown in the other ObjectContainer or also have been modified since the last time the two ObjectContainers were synchronized.

Some knowledge on the inside technology may help to use the functionality:
(1) Every object gets a UUID. For maximum speed and minimum size consumption this UUID consists of an indexed long and a reference to the "DatabaseObject" for the database the object was created on.
(2) Every object gets a version number, generated by the transaction, to track when the object was last changed.
(3) When two ObjectContainers are replicated a "ReplicationRecord" object is stored to both databases to denote after which transaction version the two databases where in sync the last time.
(4) The version numbers help to identify which objects were modified, they are decisive for the direction of replicating a single object and they denote conflicts, in case the version number of an object was changed in both databases since the last time the ObjectContainers were replicated.

Enjoy our new 4.5 version!