Transactions can be complex to understand, this page will show you which parts of the code will process objects and at which stage. This can be useful to extend the current behaviour, improve your transactions performance or simply better understand the code.
We will follow the code flow at the point where the
IOWriteHandlerInterface is called (either via
a utility class like IOHelper
, DAO
or via your own custom code (custom DAO, etc).
ObjectIOStatements defined for the object's application and for each column of this application during the mapping phase (typically on startup).
doWrite method of its
ObjectStorageWriter
(which defaults to an instance of
TransactionObjectStorageWriter)
doWrite method of the TransactionObjectStorageWriter simply adds a
WriteStatement
to the current GenericTransaction<ObjectStoreStatement> started by step 2.
nest() call or if the nested transaction is running at a different
isolation level), all the WriteStatements that were added to it are executed.
WriteStatement's execute method then starts a GenericTransactionManager for
StorageStatements.
(note: this is different from the manager which manages ObjectStoreStatements).
It also creates a trigger on the current ObjectIOStatement Transaction so that at the end of a successful commit of that transaction,
the newly created StorageStatement Transaction is itself committed.
doWriteTransaction method on the TransactionObjectStorageWriter. (see
AbstractWriteImpl)
doWriteTransaction method will then delegates to the actual storage engine's to obtain a StorageStatement.
getWriter will return a
DBUpdate
Transaction of StorageStatements.
StorageStatements,
the commit end of the ObjectStoreStatement will call execute on each StorageStatement.
@Table("Table_A")
public class A {
@Sequence @PrimaryKey
public int key = 0;
@Cascade
public B b;
}
@Table("Table_B")
public class B {
@Sequence @PrimaryKey
public int key = 0;
public String name;
}
We now simply call IOHelper.save(new A()); (after mapping the object to a schema using DBDataMapper.map(A.class))
ObjectWriteHandler creates an ObjectIOStatementImpl to represent this IO operation requestTransactionObjectWriter starts a GenericTransaction for ObjectStoreStatements. to collect the store statementsGenericTransactionHandler calls the ObjectIOStatementImpl's execute method in this new transaction context.ObjectIOStatementImpl's execute method calls:
A.b).
doWrite method of the TransactionObjectStorageWriterdoWrite() method of the TransactionObjectStorageWriter creates a WriteStatement and adds it to the ObjectStoreStatement transaction.commit() method of the GenericTransaction executes each WriteStatement in turn, it contains:
WriteStatement(B)WriteStatement(A)WriteStament(B) creates a new GenericTransaction for StorageStatements.
Then it calls doWriteTransaction on the TransactionObjectStorageWriter.
WriteStament(B) is executed, the StorageStatement transaction exists and it just calls doWriteTransaction.
doWriteTransaction for B generates a DBInsert("Table_B").doWriteTransaction for A generates a DBInsert("Table_A").
commit() has successfully processed all the StorageStatements, the
COMMIT_END trigger calls commit() on the StorageStatement transaction, which calls
execute() on each DBInsert statement it contains (DBInsert("Table_B") and DBInsert("Table_A")).
DBInsert statements to connect to the database and execute the appropriate SQL statements.
Note: in this example, the database lock is only held during part of step 9!
Between the time the first database statement requests a connection and the sucessful commit end of the StorageStatement transaction.
The database connection is automatically commited (or rolled back if needed) using another COMMIT_END (or COMMIT_FAIL) trigger on the StorageStatement transaction.