On 15 May 2014 00:57, GESCONSULTOR - Óscar Bou <o....@gesconsultor.com>wrote:

> Dan, please, correct me as needed :-))
>
> The commands are added to a queue, and that queue is emptied on each
> transaction.
>
>
correct


>  The point is that Isis, for example, generates a new transaction on each
> action invokation.
>
>
correct


> In the context of tests, that could be simulated by wrapping the calls (it
> would also force other business rules) to actions, and setters.
>
>
sort-of.

I've just been double checking as to the behaviour of transactions in
tests; it is fairly sane, I think, though not well documented.

We set up a new transaction for each test. The same transaction is present
for the setup and the test method itself, in a state of IN_PROGRESS.

You can confirm this using
IsisContext.getTransactionManager().getTransaction().getState().

IsisSystemForTest.get() is a thread-local representation of the running
system.  Using this, it is possible to commit/abort and begin new
transactions at any time:

* IsisSystem.get().commitTran()
* IsisSystem.get().abortTran()
* IsisSystem.get().beginTran()


The interaction of transactions with/without wrap() is as follows:

1. if a transaction is in progress (the default), then invoking without
wrapping (as expected) takes place in the context of that interaction; the
transaction is not committed
1. if a transaction is in progress, then wrapping - at least as far as
transactions are concerned - has no effect; the interaction is performed in
the context of the current transaction
3. if a transaction has been explicitly committed (so that none is in
progress), then invoking without wrapping will cause an exception to be
thrown ("no xactn in progress")
4. if a transaction has been explicitly committed, then wrapping will
automatically begin and commit the transaction around the interaction.

So, Oscar, your statement corresponds to option 4, and is correct if the
xactn had already been committed explicitly (in the setup, say)



> In our case, we have created a persist method on each repository that
> persists the domain object and also executes a flush.
>
>
A reasonable pattern.  I'm pretty sure that any repository query will
always do a flush anyway (analogous to Hibernate auto-flush function).



> Perhaps its performance would not be as good for bulk inserts, but in the
> context of our domain we prefer to force the flush on each persist than the
> performance gained by queueing the database commands to be sent in blocks.
>
>
If bulk inserts are ever required, then a good pattern is to define a
domain service to do this sort of work.  Then, start out with a naive
implementation that just does individual flushes, and switch in a more
performant implementation (eg calling stored procedures or whatever) if and
when required.  So long as the integration tests pass...

On the topic of performance (for queries), do note that in 1.4.0 we
introduced QueryResultsCache.  And, DN has various L2 caching options for
truly immutable data.

Cheers
Dan




> HTH,
>
> Oscar
>
>
>
>

Reply via email to