If you've used a version property then the Flush() will fail because
account1.Version will have changed between the 'read' & 'write'
operations causing an exception.  If you've neglected to use a version
then the write will of course succeed (duly destroying domain
integrity!).

This is a classic example of "pessimistic locking" vs "optimistic
locking".  The traditional "do-it-all-in-one-transaction" approach is
the pessimistic lock which [subject to normal caveats] pretty much
ensures that the operation will succeed, but at the cost of blocking
access to the entities involved by other SQL connections; OTOH, the CpBT
pattern as described below may fail if another logical process makes an
update to the account1 entity, but has the advantage of better
concurrency under most circumstances.  If this happens then you can
re-read the initial data and redo the mutation.

My personal view is that using pessimistic vs optimistic semantics
depends upon the characteristics of the [portion of the] system you're
designing.  For example, if you're routinely expecting many concurrent
updates to the same account then IMO it would be better to use a
pessimistic lock because the optimistic version will regularly fail and
need to be re-done; if you're expecting concurrent updates to be rare or
non-existent then the optimistic version is more appropriate because it
will fail rarely (e.g. if the account's details are changed by another
part of the system) so the overhead of re-doing the work will be less
significant than the concurrency degradation caused by pessimistic
locking.

HTH,

Pete Appleton

-----Original Message-----
From: [email protected] [mailto:[email protected]] On
Behalf Of pvginkel
Sent: 24 November 2011 07:40
To: nhusers
Subject: [nhusers] CpBT and transactions

In the CpBT model, a conversation goes something like this:

Create Conversation
  Resume Conversation
    Begin Transaction
      Make some updates
    Commit Transaction
  Pause Conversation
  Resume Conversation
    Begin Transaction
      Flush Session
    Commit Transaction
  Pause Conversation
Dispose Conversation

One of the things that are specifically noted in the description here
http://fabiomaulo.blogspot.com/2008/12/conversation-per-business-transac
tion.html
is that the Flush is in a separate transaction. I have the feeling
that this gives problems with constructs like:

    ...
  account1.Balance -= transaction.Amount;
  account2.Balance += transaction.Amount;
  transactionRepository.Save(transaction);
  accountRepository.Save(account1);
  accountRepository.Save(account2);

I specifically refer to the `account1.Balance -= transaction.Amount`.
This is a mutation that depends on the existing value. However,
because we read the value in a different transaction than where it is
committed, we do not have ACID guarantees.

What should I do to make the above safe? My instinct says that these
kinds of mutations could/should be executed in the last transaction
where the session is flushed, but the CpBT model specifically states
that this should not be done.

-- 
You received this message because you are subscribed to the Google
Groups "nhusers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/nhusers?hl=en.

-- 
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en.

Reply via email to