diff --git a/src/doc/development/structure.rst b/src/doc/development/structure.rst index 41fd33241250da8ce5368e1d87292e69879f6158..f5d5cb8b36f7ccdd1a7124c27827df21ee589dd9 100644 --- a/src/doc/development/structure.rst +++ b/src/doc/development/structure.rst @@ -57,13 +57,15 @@ main packages which handle the backend: :java:ref:`backend.implementation.MySQL<MySQL>` MySQL implementations of the interfaces. Typical "simple" implementations create a prepared SQL - statement from the arguments to ``execute(...)`` and send it to the SQL server. + statement from the arguments to ``execute(...)`` and send it to the SQL server. They may also + have methods for undoing and cleanup, using an :java:ref:`UndoHandler`. :java:ref:`backend.transaction<backend.transaction>` classes Subclasses of the abstract :java:ref:`BackendTransaction` which implement the ``execute()`` method. These classes may use specific backend implementations (like for example the MySQL implementations) to interact with the backend database. +For example, the structure when getting an Entity ID by name looks like this: .. uml:: @@ -71,7 +73,7 @@ main packages which handle the backend: together { abstract BackendTransaction { HashMap impl // stores all implementations - abstract execute() + {abstract} execute() } note left of BackendTransaction::impl Stores the @@ -81,7 +83,7 @@ main packages which handle the backend: end note package ...backend.interfaces { interface GetIDByNameImpl { - abstract execute(String name, String role, String limit) + {abstract} execute(String name, String role, String limit) } } } @@ -106,5 +108,71 @@ main packages which handle the backend: Transactions and Schedules -------------------------- +In CaosDB, several client requests may be handled concurrently. This poses no problem as long as +only read-only requests are processed, but writing transactions need to block other requests. +Therefore all transactions (between their first and last access) block write transactions other than +themselves from writing to the backend, while read transactions may happen at any time, except when +a write transaction actually writes to the backend. + +.. note:: + + There is a fine distinction between write transactions on the CaosDB server and actually writing + to the backend, since even transactions which need only very short write access to the backend may + require extensive read access before, for example to check for permissions or to check if the + intended write action makes sense (linked entities must exist, they may need to be of the correct + RecordType, etc.). + +The request handling in CaosDB is organized in the following way: + +- HTTP resources usually create a :java:ref:`Transaction` object and call its + :java:ref:`Transaction.execute()` method. Entities are passed to and from the transaction via + :java:ref:`TransactionContainers<TransactionContainer>` (basically normal + :java:ref:`Containers<Container>`, enriched with some metadata). +- The Transaction keeps a :java:ref:`Schedule` of related :java:ref:`Jobs<Job>` (each also wrapping + a specific Transaction), which may be called at different stages, called + :java:ref:`JobExecutionTimes<JobExecutionTime>`. +- The Transaction's ``execute()`` method, when called, in turn calls a number of methods for + initialization, checks, preparations, cleanup etc. Additionally the scheduled jobs are executed + at their specified stages, for example all jobs scheduled for ``INIT`` are executed immediately + after calling ``Transaction.init()``. Please consult the API documentation for + :java:ref:`Transaction.execute()` for details. + + Most importantly, the (abstract) method ``transaction()`` is called by ``execute()``, which in + inheriting classes typically interacts with the backend via :java:ref:`execute(BackendTransaction, + Access)<Transaction.execute(K t, Access access)>`, which in turn calls the + ``BackendTransaction``'s :java:ref:`BackendTransaction.executeTransaction()` method (just a thin + wrapper around its ``execute()`` method). + +Summarized, the classes are connected like this: +.. uml:: + + @startuml + hide empty members + + class Container + class TransactionContainer extends Container + + abstract Transaction { + Schedule schedule + TransactionContainer container + execute() + execute(BackendTransaction t, Access access)\n // -> t.executeTransaction(t) + } + + class Schedule + class ScheduledJob + abstract Job { + ExecutionTime time + Transaction transaction + execute(BackendTransaction t)\n // -> transaction.execute(t, transaction.access) + } + + Schedule "*" *- ScheduledJob + ScheduledJob *- Job + Job o--d- Transaction + + TransactionContainer -* Transaction::container + Transaction::schedule *- Schedule + @enduml