From the API side, there's no real difference between transactions executing concurrently within the same VM and transactions executed against a remote server. To use concurrent transactions within a single VM, we just open a db4o server on our database file, directing it to run on port 0, thereby declaring that no networking will take place.
01private static void AccessLocalServer() 02
{ 03
IObjectServer server = Db4oFactory.OpenServer(Db4oFileName, 0); 04
try 05
{ 06
IObjectContainer client = server.OpenClient(); 07
// Do something with this client, or open more clients 08
client.Close(); 09
} 10
finally 11
{ 12
server.Close(); 13
} 14
}
01Public Shared Sub AccessLocalServer() 02
Dim server As IObjectServer = Db4oFactory.OpenServer(Db4oFileName, 0) 03
Try 04
Dim client As IObjectContainer = server.OpenClient() 05
' Do something with this client, or open more clients 06
client.Close() 07
Finally 08
server.Close() 09
End Try 10
End Sub
Again, we will delegate opening and closing the server to our environment to focus on client interactions.
1private static void QueryLocalServer(IObjectServer server) 2
{ 3
IObjectContainer client = server.OpenClient(); 4
ListResult(client.Get(new Car(null))); 5
client.Close(); 6
}
1Public Shared Sub QueryLocalServer(ByVal server As IObjectServer) 2
Dim client As IObjectContainer = server.OpenClient() 3
ListResult(client.Get(New Car(Nothing))) 4
client.Close() 5
End Sub
The transaction level in db4o is read committed. However, each client container maintains its own weak reference cache of already known objects. To make all changes committed by other clients immediately, we have to explicitly refresh known objects from the server. We will delegate this task to a specialized version of our listResult() method.
1private static void ListRefreshedResult(IObjectContainer container, IObjectSet items, int depth) 2
{ 3
System.Console.WriteLine(items.Count); 4
foreach (object item in items) 5
{ 6
container.Ext().Refresh(item, depth); 7
System.Console.WriteLine(item); 8
} 9
}
1Public Shared Sub ListRefreshedResult(ByVal container As IObjectContainer, ByVal items As IObjectSet, ByVal depth As Integer) 2
Console.WriteLine(items.Count) 3
For Each item As Object In items 4
container.Ext().Refresh(item, depth) 5
Console.WriteLine(item) 6
Next 7
End Sub
01private static void DemonstrateLocalReadCommitted(IObjectServer server) 02
{ 03
IObjectContainer client1 =server.OpenClient(); 04
IObjectContainer client2 =server.OpenClient(); 05
Pilot pilot = new Pilot("David Coulthard", 98); 06
IObjectSet result = client1.Get(new Car("BMW")); 07
Car car = (Car)result.Next(); 08
car.Pilot = pilot; 09
client1.Set(car); 10
ListResult(client1.Get(new Car(null))); 11
ListResult(client2.Get(new Car(null))); 12
client1.Commit(); 13
ListResult(client1.Get(typeof(Car))); 14
ListRefreshedResult(client2, client2.Get(typeof(Car)), 2); 15
client1.Close(); 16
client2.Close(); 17
}
01Public Shared Sub DemonstrateLocalReadCommitted(ByVal server As IObjectServer) 02
Dim client1 As IObjectContainer = server.OpenClient() 03
Dim client2 As IObjectContainer = server.OpenClient() 04
Dim pilot As Pilot = New Pilot("David Coulthard", 98) 05
Dim result As IObjectSet = client1.Get(New Car("BMW")) 06
Dim car As Car = DirectCast(result.Next(), Car) 07
car.Pilot = pilot 08
client1.Set(car) 09
ListResult(client1.Get(New Car(Nothing))) 10
ListResult(client2.Get(New Car(Nothing))) 11
client1.Commit() 12
ListResult(client1.Get(GetType(Car))) 13
ListRefreshedResult(client2, client2.Get(GetType(Car)), 2) 14
client1.Close() 15
client2.Close() 16
End Sub
Simple rollbacks just work as you might expect now.
01private static void DemonstrateLocalRollback(IObjectServer server) 02
{ 03
IObjectContainer client1 = server.OpenClient(); 04
IObjectContainer client2 = server.OpenClient(); 05
IObjectSet result = client1.Get(new Car("BMW")); 06
Car car = (Car)result.Next(); 07
car.Pilot = new Pilot("Someone else", 0); 08
client1.Set(car); 09
ListResult(client1.Get(new Car(null))); 10
ListResult(client2.Get(new Car(null))); 11
client1.Rollback(); 12
client1.Ext().Refresh(car, 2); 13
ListResult(client1.Get(new Car(null))); 14
ListResult(client2.Get(new Car(null))); 15
client1.Close(); 16
client2.Close(); 17
}
01Public Shared Sub DemonstrateLocalRollback(ByVal server As IObjectServer) 02
Dim client1 As IObjectContainer = server.OpenClient() 03
Dim client2 As IObjectContainer = server.OpenClient() 04
Dim result As IObjectSet = client1.Get(New Car("BMW")) 05
Dim car As Car = DirectCast(result.Next(), Car) 06
car.Pilot = New Pilot("Someone else", 0) 07
client1.Set(car) 08
ListResult(client1.Get(New Car(Nothing))) 09
ListResult(client2.Get(New Car(Nothing))) 10
client1.Rollback() 11
client1.Ext().Refresh(car, 2) 12
ListResult(client1.Get(New Car(Nothing))) 13
ListResult(client2.Get(New Car(Nothing))) 14
client1.Close() 15
client2.Close() 16
End Sub