The use of depth parameter in deactivate
call from
the previous example directly affects performance: the
less is the depth the less objects will need to be re-read from the database
and the better the performance will be. Ideally we only want to deactivate the
objects that were changed in the rolled-back transaction. This can be done by
providing a special class for db4o configuration. This class should implement
RollbackStrategy/IRollbackStrategy
interface and is configured as
part of Transparent Persistence support:
TPRollback.cs: RollbackDeactivateStrategy private class RollbackDeactivateStrategy : IRollbackStrategy { public void Rollback(IObjectContainer container, Object obj) { container.Ext().Deactivate(obj); } }
TPRollback.cs: ConfigureTPForRollback
private static IConfiguration ConfigureTPForRollback()
{
IConfiguration configuration = Db4oFactory.NewConfiguration();
// add TP
support and rollback strategy
configuration.Add(new TransparentPersistenceSupport(
new RollbackDeactivateStrategy()));
return configuration;
}
TPRollback.vb: RollbackDeactivateStrategy Private Class RollbackDeactivateStrategy Implements IRollbackStrategy Public Sub Rollback(ByVal container As IObjectContainer, _ ByVal obj As Object) _ Implements IRollbackStrategy.Rollback container.Ext().Deactivate(obj) End Sub End Class
TPRollback.vb: ConfigureTPForRollback Private Shared Function ConfigureTPForRollback() As IConfiguration Dim configuration As IConfiguration = Db4oFactory.NewConfiguration() ' add TP support and rollback strategy configuration.Add(New TransparentPersistenceSupport _ (New RollbackDeactivateStrategy())) Return configuration End Function
RollbackDeactivateStrategy#rollback method will be automatically called once per each modified object after the rollback. Thus you do not have to worry about deactivate depth anymore - all necessary deactivation will happen transparently preserving the best performance possible.
TPRollback.cs: ModifyWithRollbackStrategy private static void ModifyWithRollbackStrategy() { IObjectContainer container = Database(ConfigureTPForRollback()); if (container != null) { try { // create a car Car car = (Car)container.QueryByExample(new Car(null, null)) [0]; Pilot pilot = car.Pilot; System.Console.WriteLine("Initial car: " + car + "(" + container.Ext().GetID(car) + ")"); System.Console.WriteLine("Initial pilot: " + pilot + "(" + container.Ext().GetID(pilot) + ")"); car.Model = "Ferrari"; car.ChangePilot("Michael Schumacher", 123); container.Rollback(); System.Console.WriteLine("Car after rollback: " + car + "(" + container.Ext().GetID(car) + ")"); System.Console.WriteLine("Pilot after rollback: " + pilot + "(" + container.Ext().GetID(pilot) + ")"); } finally { CloseDatabase(); } } }
TPRollback.vb: ModifyWithRollbackStrategy Private Shared Sub ModifyWithRollbackStrategy() Dim container As IObjectContainer = Database(ConfigureTPForRollback()) If container IsNot Nothing Then Try ' create a car Dim car As Car = DirectCast(container. _ QueryByExample(New Car(Nothing, Nothing))(0), Car) Dim pilot As Pilot = car.Pilot System.Console.WriteLine("Initial car: " + _ car.ToString() + "(" + container.Ext().GetID(car).ToString() + ")") System.Console.WriteLine("Initial pilot: " + _ pilot.ToString() + "(" + _ container.Ext().GetID(pilot).ToString() + ")") car.Model = "Ferrari" car.ChangePilot("Michael Schumacher", 123) container.Rollback() System.Console.WriteLine("Car after rollback: " + _ car.ToString() + "(" + _ container.Ext().GetID(car).ToString() + ")") System.Console.WriteLine("Pilot after rollback: " + _ pilot.ToString() + _ "(" + container.Ext().GetID(pilot).ToString() + ")") Finally CloseDatabase() End Try End If End Sub
Note, that RollbackDeactivateStrategy only works for activatable objects. To see the different you can comment out Activatable implementation in Id class (id value will be preserved in the cache).
Download example code: