Transaction

All work within db4o ObjectContainer is transactional. A transaction is implicitly started when you open a container, and the current transaction is implicitly committed when you close it again.

Commit And Rollback

You may choose to make a commit explicit or you may leave it for the #close() call:

TransactionExample.cs: StoreCarCommit
1public static void StoreCarCommit(IObjectContainer db) 2 { 3 Pilot pilot = new Pilot("Rubens Barrichello", 99); 4 Car car = new Car("BMW"); 5 car.Pilot = pilot; 6 db.Set(car); 7 db.Commit(); 8 }
TransactionExample.cs: ListAllCars
1public static void ListAllCars(IObjectContainer db) 2 { 3 IObjectSet result = db.Get(typeof(Car)); 4 ListResult(result); 5 }

TransactionExample.vb: StoreCarCommit
1Public Shared Sub StoreCarCommit(ByVal db As IObjectContainer) 2 Dim pilot As Pilot = New Pilot("Rubens Barrichello", 99) 3 Dim car As Car = New Car("BMW") 4 car.Pilot = pilot 5 db.[Set](car) 6 db.Commit() 7 End Sub

TransactionExample.vb: ListAllCars
1Public Shared Sub ListAllCars(ByVal db As IObjectContainer) 2 Dim result As IObjectSet = db.[Get](GetType(Car)) 3 ListResult(result) 4 End Sub

Before transaction is commited all the modifications to a database are written to a temporary memory storage. Commit (explicit or implicit) writes the modifications to the disk.

Please, remember to always commit or close your ObjectContainer when the work is done, to make sure that the data is saved to the permanent storage.

If you do not want to save changes to the database, you can call rollback, resetting the state of our database to the last commit point.

TransactionExample.cs: StoreCarRollback
1public static void StoreCarRollback(IObjectContainer db) 2 { 3 Pilot pilot = new Pilot("Michael Schumacher", 100); 4 Car car = new Car("Ferrari"); 5 car.Pilot = pilot; 6 db.Set(car); 7 db.Rollback(); 8 }

TransactionExample.cs: ListAllCars
1public static void ListAllCars(IObjectContainer db) 2 { 3 IObjectSet result = db.Get(typeof(Car)); 4 ListResult(result); 5 }

TransactionExample.vb: StoreCarRollback
1Public Shared Sub StoreCarRollback(ByVal db As IObjectContainer) 2 Dim pilot As Pilot = New Pilot("Michael Schumacher", 100) 3 Dim car As Car = New Car("Ferrari") 4 car.Pilot = pilot 5 db.[Set](car) 6 db.Rollback() 7 End Sub

TransactionExample.vb: ListAllCars
1Public Shared Sub ListAllCars(ByVal db As IObjectContainer) 2 Dim result As IObjectSet = db.[Get](GetType(Car)) 3 ListResult(result) 4 End Sub

Refresh Live Objects

There is one thing that you should remember when rolling back: the #rollback() method will cancel the modifications, but it won't change back the state of the objects in your reference cache.

TransactionExample.cs: CarSnapshotRollback
1public static void CarSnapshotRollback(IObjectContainer db) 2 { 3 IObjectSet result = db.Get(new Car("BMW")); 4 Car car = (Car)result.Next(); 5 car.Snapshot(); 6 db.Set(car); 7 db.Rollback(); 8 Console.WriteLine(car); 9 }

TransactionExample.vb: CarSnapshotRollback
1Public Shared Sub CarSnapshotRollback(ByVal db As IObjectContainer) 2 Dim result As IObjectSet = db.[Get](New Car("BMW")) 3 Dim car As Car = DirectCast(result.[Next](), Car) 4 car.Snapshot() 5 db.[Set](car) 6 db.Rollback() 7 Console.WriteLine(car) 8 End Sub

You have to explicitly refresh your live objects when their state might become different from the state in the database:

TransactionExample.cs: CarSnapshotRollbackRefresh
01public static void CarSnapshotRollbackRefresh(IObjectContainer db) 02 { 03 IObjectSet result=db.Get(new Car("BMW")); 04 Car car=(Car)result.Next(); 05 car.Snapshot(); 06 db.Set(car); 07 db.Rollback(); 08 db.Ext().Refresh(car, int.MaxValue); 09 Console.WriteLine(car); 10 }

TransactionExample.vb: CarSnapshotRollbackRefresh
1Public Shared Sub CarSnapshotRollbackRefresh(ByVal db As IObjectContainer) 2 Dim result As IObjectSet = db.[Get](New Car("BMW")) 3 Dim car As Car = DirectCast(result.[Next](), Car) 4 car.Snapshot() 5 db.[Set](car) 6 db.Rollback() 7 db.Ext().Refresh(car, Integer.MaxValue) 8 Console.WriteLine(car) 9 End Sub

The #refresh() method might be also helpful when the changes to the database are done from different threads. See Client-Server for more information.