In the latest build we have introduced an even stricter Exception handling. The new strategy: If the exception occured is a Db4oRecoverableException we rethrow this exception to the user application. In all other cases we do an emergency shutdown of the ObjectContainer/ObjectServer without commit, without even writing FreeSpace information. This way we try to do our best to keep the database in the last committed state.
The new behaviour is quite different to the previous behaviour where we did not catch VM errors. In Client/Server mode an OutOfMemoryError for a specific client would have only terminated the handling thread for the client that it serviced. The server would have continued to work. For this case there was a small risk that BTrees or cache pages ended up in an inconsistent state.
The change of the Exception handling is also relevant for single user mode: If db4o would have been accessed by multiple threads, the one thread that experienced an OutOfMemoryException would have died. Other threads with references to the same ObjectContainer may have worked on, also against a possibly inconsistent state.
Now we make sure the ObjectContainer becomes unusable as soon as any unexpected Exception occurs.
We have also tried to improve against the possible risk of shadowed exceptions: In case exceptions occur during the emergency shutdown, we wrap all occurred exceptions in a CompositeDb4oException to make sure no exception information gets lost.
For callbacks and events that call into user code we wrap possible exceptions into Db4oRecoverableException. That way we try to ensure that exceptions that occur outside of the db4o core do not shut down ObjectContainers. For these cases it is up to your application to decide what to do.
We plan to continue improving local exception handling to catch even more cases where it is safe to keep an ObjectContainer alive.
As always we rely on your feedback. Please tell us how you like the new Exception handling and how it works for you.