Skip to content

Dirty Check

Jan Wiemer edited this page Jan 11, 2022 · 5 revisions

Dirty Check

As already mentioned by default there is no automatic dirty check for JACIS. Modified objects in the TX-View of a transaction are only stored back to the original values if the store is explicitly notified about the modification by calling the update (or remove) method. The reason is twofold:

  • A generic dirty check would require comparing the state of the committed object and the TX-View of the object e.g. by reflection which is a bit of magic and should be avoided according to the design principles (at least for the default version of the store).

  • During each commit (more exactly in the prepare phase) a dirty check has to traverse all objects in the TX-View of the transaction. Doing a complex compare operation (including reflection) for each object may become a bit of a performance problem.

On the other hand a dirty check would prevent us from the danger to forget an update call after a modification (which could cause problems that are not easy to analyse). Therefore it is possible to extend the JACIS with a dirty check. A default version with the idea to mark the objects as dirty on each modification is already included and can simply be activated (see below). In the chapter Custom Dirty Checks it is described how to extend a store with custom implementations of a dirty check.

The default implementation of the dirty check (class: StoreEntryBasedDirtyCheck) works with the idea to track a modification directly at the modified object. For this purpose the stored objects have to implement the JacisDirtyTrackingObject interface declaring a method isDirty to check if the object is dirty. It is very simple to implement this interface if we are anyway working with objects providing a read only mode by extending the AbstractReadOnlyModeSupportingObject class (see chapter Read Only Objects) since all modifying methods have to call the checkWritable method. The abstract class AbstractReadOnlyModeAndDirtyCheckSupportingObject extends the AbstractReadOnlyModeSupportingObject and additionally tracks that the object is dirty whenever the checkWritable method is called.

Therefore to use the default dirty check doing the following is enough:

  • let the stored objects extend the AbstractReadOnlyModeAndDirtyCheckSupportingObject and all modifying methods call the checkWritable method;

  • switch the default dirty check on by calling the setObjectBasedDirtyCheck method at the JacisObjectTypeSpec of the store.

    JacisContainer container = new JacisContainer();
    JacisObjectTypeSpec<String, Account, Account> objectTypeSpec = //
        new JacisObjectTypeSpec<>(String.class, Account.class, new JacisCloningObjectAdapter<>());
    objectTypeSpec.setObjectBasedDirtyCheck(); // *** switch on automatic dirty check ***
    JacisStore<String, Account> store = container.createStore(objectTypeSpec).getStore();

    container.withLocalTx(() -> { // First we create a test account...
      store.update("account1", new Account("account1").deposit(100));
    });
    container.withLocalTx(() -> { // Output balance before modification...
      System.out.println("balance: " + store.get("account1").getBalance());
    });
    container.withLocalTx(() -> { // Modify the balance relying on dirty check
      store.get("account1").deposit(500); // *** no update call! ***
    });
    container.withLocalTx(() -> { // Output balance after modification...
      System.out.println("balance: " + store.get("account1").getBalance());
    });

Next Chapter: Indices