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. db4o transaction is tied to an open object container and only one transaction is allowed per object container instance.
You may choose to make a commit explicit or you may leave it for the #close()
call:
1private 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
}
1private static void ListAllCars(IObjectContainer db) 2
{ 3
IObjectSet result = db.Get(typeof(Car)); 4
ListResult(result); 5
}
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
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. Commit Strategies contains some important information on when and how commit should be used to achieve the best performance.
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.
1private 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
}
1private static void ListAllCars(IObjectContainer db) 2
{ 3
IObjectSet result = db.Get(typeof(Car)); 4
ListResult(result); 5
}
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
1Public Shared Sub ListAllCars(ByVal db As IObjectContainer) 2
Dim result As IObjectSet = db.Get(GetType(Car)) 3
ListResult(result) 4
End Sub
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.
1private 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
}
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:
01private 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
}
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.