[This is preliminary documentation and is subject to change.]
The handler is called if a PersistateDatabaseException is raised during database operations. This can happen in several circumstances. First of all, it can happen as objects are retrieved from persistent storage as and when they are accessed in the persistent tree.
Exceptions can also be raised as more fundamental operations are enacted on a data source. Examples of this are database creation, system initialisation or schema changes as a result of working with the Persistate Add-In.
Exceptions can be raised any number of times as objects are being written to persistent storage, with a DatabaseResultType of UpdateConflict. You can resolve each update conflict by returning outcomes of UseLocal or useRemote. In such cases, the commit process continues.
Finally, the handler can be called when operation executions are committed, after all updates have been made. All DatabaseResultTypes except UpdateConflict can appear here. In this case any outcome except UseLocal or UseRemote can be returned.
Note that an UpdateConflict can arise because another process has deleted the object you're trying to update. In this case, the remote version in the DatabaseExceptionArgs will be null, and it is the responsibility of the handler to adjust the object graph in memory appropriately - usually by removing the object from it's parent.
You can supply a DatabaseExceptionHandler in one of two ways. Firstly, you can set a default handler for the session by using DefaultDatabaseExceptionHandler. This is the only way to supply a handler to deal with exceptions outside of Execution commits. For Execution commits, you can supply a handler within the ExecutionResult object you return at the end of the operation execution.
If you don't supply any handler, either to DefaultDatabaseExceptionHandler of in an ExecutionResult, then StandardDatabaseExceptionHandler is used.