neo4j/neo4j — pull request #672 by jakewins (2013-04-01 16:38:17+00:00)
Title: Added internal support for running transactions via the REST API.

o Introduced new transactional endpoint, supporting cypher only, as per
design discussion with Ian and Tobias.
o Uses it's own streaming JSON serialization and deserialization, in order
to support handling errors that occur after streaming results has started.
o Include configurable transaction timeout, defaulting to 60 seconds.
o Uses the new Kernel API, creating a StatementContext for each statement,
and doing transaction management through TranactionContext.rollback/commit.
The latter done by wrapping TranactionContext in a decorator that does necessary
fiddling with TxManager.
o Compared performance between Jetty, Jetty + Servlet and Jetty + Servlet + Jersey.
No noticable difference found (300 op/s/client each), so went for the high-level
jersey approach.

Design overview:

TransactionalService
|
TransactionalActions
|
----|------------|-------------------|
| | |
KernelAPI ExecutionEngine TransactionRegistry
|
TimeoutTask

TransactionalService handles the HTTP abstraction, delegating incoming requests to appropriate
TransactionalAction methods. This includes wrapping incoming streams in serialization and deserialization
classes.

TransactionalActions handles the domain logic of creating, storing, committing and rolling back transactions,
as well as executing statements against them.

KernelAPI is actually wrapped by a class called TransitionalPeriodTransactionMessContainer, which implements
the KernelAPI interface, and adds decorators to hide the current messiness of transaction management from the
rest of the implementation. This abstraction leaks slightly in TransactionRegistry, I could not find a way around that.

TransactionRegistry stores transactions that are currently opened and unused in a thread safe way. It is called
intermittently by an external task (handled by the kernels JobScheduler), which asks the registry to evict transactions
that have been idle longer than a user-defined threshold.

Missing:
o Documentation, by design.
o StatementContext is not yet passed to Cypher, only the mechanism for creating it is in place.
A separate commit should make appropriate changes in cypher to provide for injecting statement context.
o RuntimeException when calling ExecutionResult.iterator().next() is handled gracefully from a Transaction POV,
but result sent back to user will potentially be invalid JSON. This needs to be resolved before publicly
documenting this feature.
o Logging is minimal so far, only transaction eviction is logged, and only if rollback fails. Improved logging
should be added before documenting this feature.

Details:
o For an overview of how the API works, please refer to the TransactionFunctionalTest integration test.