You are here: Basic Concepts > Transaction

Transaction

All work within db4o ObjectContainer is transactional. A transaction is implicitly started when you open a container, and the current transaction is implicitly committed when you close it again. db4o transaction is tied to an open object container and only one transaction is allowed per object container instance.

Commit And Rollback

You may choose to make a commit explicit or you may leave it for the #close() call:

TransactionExample.java: storeCarCommit
private static void storeCarCommit(ObjectContainer container)  {
        Pilot pilot=new Pilot("Rubens Barrichello",99);
        Car car=new Car("BMW");
        car.setPilot(pilot);
        container.store(car);
        container.commit();
    }
TransactionExample.java: listAllCars
private static void listAllCars(ObjectContainer container)  {
        ObjectSet result=container.queryByExample(Car.class);
        listResult(result);
    }

Before transaction is commited all the modifications to a database are written to a temporary memory storage. Commit (explicit or implicit) writes the modifications to the disk.

Please, remember to always commit or close your ObjectContainer when the work is done, to make sure that the data is saved to the permanent storage. Commit Strategies contains some important information on when and how commit should be used to achieve the best performance.

If you do not want to save changes to the database, you can call rollback, resetting the state of our database to the last commit point.

TransactionExample.java: storeCarRollback
private static void storeCarRollback(ObjectContainer container)  {
        Pilot pilot=new Pilot("Michael Schumacher",100);
        Car car=new Car("Ferrari");
        car.setPilot(pilot);
        container.store(car);
        container.rollback();
    }

Refresh Live Objects

There is one thing that you should remember when rolling back: the #rollback() method will cancel the modifications, but it won't change back the state of the objects in your reference cache.

TransactionExample.java: carSnapshotRollback
private static void carSnapshotRollback(ObjectContainer container)  {
        ObjectSet result=container.queryByExample(new Car("BMW"));
        Car car=(Car)result.next();
        car.snapshot();
        container.store(car);
        container.rollback();
        System.out.println(car);
    }

You have to explicitly refresh your live objects when their state might become different from the state in the database:

TransactionExample.java: carSnapshotRollbackRefresh
private static void carSnapshotRollbackRefresh(ObjectContainer container)  {
        ObjectSet result=container.queryByExample(new Car("BMW"));
        Car car=(Car)result.next();
        car.snapshot();
        container.store(car);
        container.rollback();
        container.ext().refresh(car,Integer.MAX_VALUE);
        System.out.println(car);
    }

The #refresh() method might be also helpful when the changes to the database are done from different threads. See Client-Server for more information.

Download example code:

Java