Automatic Deactivation


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
1private class RollbackDeactivateStrategy : IRollbackStrategy 2 { 3 public void Rollback(IObjectContainer container, Object obj) 4 { 5 container.Ext().Deactivate(obj); 6 } 7 }
TPRollback.cs: ConfigureTPForRollback
1private static IConfiguration ConfigureTPForRollback() 2 { 3 IConfiguration configuration = Db4oFactory.NewConfiguration(); 4 // add TP support and rollback strategy 5 configuration.Add(new TransparentPersistenceSupport( 6 new RollbackDeactivateStrategy())); 7 return configuration; 8 }
TPRollback.vb: RollbackDeactivateStrategy
1Private Class RollbackDeactivateStrategy 2 Implements IRollbackStrategy 3 Public Sub Rollback(ByVal container As IObjectContainer, ByVal obj As Object) _ 4 Implements IRollbackStrategy.Rollback 5 container.Ext().Deactivate(obj) 6 End Sub 7 End Class
TPRollback.vb: ConfigureTPForRollback
1Private Shared Function ConfigureTPForRollback() As IConfiguration 2 Dim configuration As IConfiguration = Db4oFactory.NewConfiguration() 3 ' add TP support and rollback strategy 4 configuration.Add(New TransparentPersistenceSupport(New RollbackDeactivateStrategy())) 5 Return configuration 6 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
01private static void ModifyWithRollbackStrategy() 02 { 03 IObjectContainer container = Database(ConfigureTPForRollback()); 04 if (container != null) 05 { 06 try 07 { 08 // create a car 09 Car car = (Car)container.QueryByExample(new Car(null, null)) 10 [0]; 11 Pilot pilot = car.Pilot; 12 System.Console.WriteLine("Initial car: " + car + "(" 13 + container.Ext().GetID(car) + ")"); 14 System.Console.WriteLine("Initial pilot: " + pilot + "(" 15 + container.Ext().GetID(pilot) + ")"); 16 car.Model = "Ferrari"; 17 car.ChangePilot("Michael Schumacher", 123); 18 container.Rollback(); 19 System.Console.WriteLine("Car after rollback: " + car + "(" 20 + container.Ext().GetID(car) + ")"); 21 System.Console.WriteLine("Pilot after rollback: " + pilot + "(" 22 + container.Ext().GetID(pilot) + ")"); 23 } 24 finally 25 { 26 CloseDatabase(); 27 } 28 } 29 }
TPRollback.vb: ModifyWithRollbackStrategy
01Private Shared Sub ModifyWithRollbackStrategy() 02 Dim container As IObjectContainer = Database(ConfigureTPForRollback()) 03 If container IsNot Nothing Then 04 Try 05 ' create a car 06 Dim car As Car = DirectCast(container.QueryByExample(New Car(Nothing, Nothing))(0), Car) 07 Dim pilot As Pilot = car.Pilot 08 System.Console.WriteLine("Initial car: " + car.ToString() + "(" + container.Ext().GetID(car).ToString() + ")") 09 System.Console.WriteLine("Initial pilot: " + pilot.ToString() + "(" + container.Ext().GetID(pilot).ToString() + ")") 10 car.Model = "Ferrari" 11 car.ChangePilot("Michael Schumacher", 123) 12 container.Rollback() 13 System.Console.WriteLine("Car after rollback: " + car.ToString() + "(" + container.Ext().GetID(car).ToString() + ")") 14 System.Console.WriteLine("Pilot after rollback: " + pilot.ToString() + "(" + container.Ext().GetID(pilot).ToString() + ")") 15 Finally 16 CloseDatabase() 17 End Try 18 End If 19 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).