You are here: Client-Server > Reference Cache In Client-Server Mode

Reference Cache In Client-Server Mode

db4o uses an object reference cache for easy access to persistent objects during one transaction. In client/server mode each client has its own reference cache, which helps to achieve good performance. However it gets complicated, when different clients work on the same object, as this object's cached value is used on each side. It means, that even when the operations go serially, the object's value won't be updated serially unless it is refreshed before each update.

Person personOnClient1 = QueryForPerson(client1);
Person personOnClient2 = QueryForPerson(client2);
Console.Write(QueryForPerson(client2).Name);

personOnClient1.Name = ("New Name");
client1.Store(personOnClient1);
client1.Commit();

// The other client still has the old data in the cache
Console.Write(QueryForPerson(client2).Name);

client2.Ext().Refresh(personOnClient2, int.MaxValue);

// After refreshing the date is visible
Console.Write(QueryForPerson(client2).Name);
ReferenceCacheExamples.cs: Reference cache in client server
Dim personOnClient1 As Person = QueryForPerson(client1)
Dim personOnClient2 As Person = QueryForPerson(client2)
Console.Write(QueryForPerson(client2).Name)

personOnClient1.Name = ("New Name")
client1.Store(personOnClient1)
client1.Commit()

' The other client still has the old data in the cache
Console.Write(QueryForPerson(client2).Name)

client2.Ext().Refresh(personOnClient2, Integer.MaxValue)

' After refreshing the date is visible
Console.Write(QueryForPerson(client2).Name)
ReferenceCacheExamples.vb: Reference cache in client server

There are multiple strategies to deal with this.

Clean Cache For Work

Often you don't want to refresh object by object. Instead you want to work with a clean cache. You can do this by using a separate 'session' on the client. This container brings its own cache with it. So you can create a new container which a clean cache.

Note that open session on the client doesn't create a separate transaction. Instead it only creates a fresh cache. The transaction is always the same.

using (IObjectContainer container = client.Ext().OpenSession())
{
    // do work
}
// Start with a fresh cache:
using (IObjectContainer container = client.Ext().OpenSession())
{
    // do work
}
ReferenceCacheExamples.cs: Clean cache for each unit of work
Using container As IObjectContainer = client.Ext().OpenSession()
    ' do work
End Using
' Start with a fresh cache:
Using container As IObjectContainer = client.Ext().OpenSession()
    ' do work
End Using
ReferenceCacheExamples.vb: Clean cache for each unit of work