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:
1private class RollbackDeactivateStrategy : IRollbackStrategy 2
{ 3
public void Rollback(IObjectContainer container, Object obj) 4
{ 5
container.Ext().Deactivate(obj); 6
} 7
}
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
}
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
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.
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
}
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).