Skip to content

Getting Started

Jan Wiemer edited this page Dec 27, 2020 · 13 revisions

Getting Started

Before starting to implement an application using JACIS the steps described in the chapter of this manual have to be done.

Having this done we create a simple example class of objects that shall be stored in a transactional store. The class implements the JacisCloneable interface to enable the store to clone the object without using Furthermore the class extends the AbstractReadOnlyModeSupportingObject (implementing the JacisReadonlyModeSupport interface). This means the object provides a secure read only mode. It is the responsibility of an object implementing the JacisReadonlyModeSupport interface to prevent any modification after the method switchToReadOnlyMode is called. The AbstractReadOnlyModeSupportingObject provides a checkWritable method throwing an exception if the object is in read only mode.

  public class Account extends AbstractReadOnlyModeSupportingObject implements JacisCloneable<Account> {

    private final String name;
    private long balance;

    public Account(String name) {
      this.name = name;
    }

    @Override
    public Account clone() {
      return (Account) super.clone();
    }

    Account deposit(long amount) {
      checkWritable();
      balance += amount;
      return this;
    }

    public Account withdraw(long amount) {
      checkWritable();
      balance -= amount;
      return this;
    }

    public String getName() {
      return name;
    }

    public long getBalance() {
      return balance;
    }

  }

First we initialize a JACIS container:

    JacisContainer container = new JacisContainer();

Now we create a store for our example object:

    JacisObjectTypeSpec<String, Account, Account> objectTypeSpec = new JacisObjectTypeSpec<>(String.class, Account.class, new JacisCloningObjectAdapter<>());
    JacisStore<String, Account> store = container.createStore(objectTypeSpec).getStore();

Now we start a local transaction on the JACIS container (that means on all stores of this container):

    JacisLocalTransaction tx = container.beginLocalTransaction();

Now we can work with the store (inside a transaction) and create and update objects. First we create a new Account:

    Account account1 = new Account("account1");

All modifications of objects have to be notified to the store explicitly (there is no automatic dirty checking). This is true for modifications as well as for creating new objects. In both cases the store is notified by calling the update method:

    store.update(account1.getName(), account1);

Enough for our first transaction. Now we commit the transaction. Afterwards all other transactions can see our new Account

    tx.commit();

For our next transaction we use a helper method executing the passed code (as lambda expression) inside a transaction. We use this to deposit some money on our account. Note that the call of the update is again necessary. If we omit this call the change will be lost after commit (try it).

    container.withLocalTx(() -> {
      Account acc = store.get("account1");
      acc.deposit(100);
      store.update("account1", acc);
    });

We use another transaction to check the balance of the Account:

    container.withLocalTx(() -> {
      Account acc = store.get("account1");
      System.out.println("balance of " + acc.getName() + ": " + acc.getBalance());
    });

Finally we withdraw some money and simulate an exception causing the transaction to be rolled back:

    try {
      container.withLocalTx(() -> {
        Account acc = store.get("account1");
        acc.withdraw(10);
        store.update("account1", acc);
        throw new RuntimeException("Error in transaction!");
      });
    } catch (RuntimeException e) {
      System.out.println("Expected exception " + e);
      // expected
    }

Again we check the balance of the Account to see that the transaction failed and nothing is withdrawn:

    container.withLocalTx(() -> {
      Account acc = store.get("account1");
      System.out.println("balance of " + acc.getName() + ": " + acc.getBalance());
    });

Next Chapter: Accessing Objects

Clone this wiki locally