Question on the exact semantics of beforeCommit?

27 views
Skip to first unread message

Andy

unread,
Jan 23, 2013, 3:04:39 PM1/23/13
to scala-stm-e...@googlegroups.com
Hello,

Let me start by saying great job. STM has worked great for me. I am not fully clear reading the scala docs on the semantics of beforeCommit. 

1. Does beforeCommit means that the transaction has completed successfully but is not yet visible to outside transactions?
2. In what instance would beforeCommit be executed but the transaction fail?
3. Will beforeCommit ever be retried?
4. If an exception is thrown in beforeCommit is the transaction rolled back?

Thanks a bunch,
Andrew

Nathan Bronson

unread,
Jan 23, 2013, 3:33:00 PM1/23/13
to scala-stm-e...@googlegroups.com
Andrew,

I'm glad the STM is working well for you.

beforeCommit runs just before the STM tries to commit the transaction, as if it is the last action in the body of the outermost atomic block.

1. No, the transaction might still fail during or after beforeCommit has run.

2. The most likely scenario for a failure after beforeCommit has executed is that some of the transaction's reads were stale, but it wasn't discovered until the final commit check. Also possible: a higher priority transaction has stolen write permission from the current transaction, a later callback caused a failure, or there is an ExternalDecider that decided not to commit.

3. Yes, beforeCommit can be retried.

4. Yes, if an exception is thrown from beforeCommit then the transaction will be rolled back and not retried. This is basically the same as if the exception was thrown from inside the atomic block itself (except that we don't try to catch control flow exceptions from in the beforeCommit stage).

whilePreparing handlers are closer to what you are asking for. They run after the STM is satisfied that commit is allowable (but still not "decided"), so only other handlers can cause rollback. If you are integrating with a transactional resource like a DB then this is the right time to call XAResource.prepare() (with the followup in an afterCommit handler).

The single moment at which the commit decision is made can be controlled by setting an ExternalDecider. If you are trying to integrate with a non-transactional resource that might fail, this is the only option. The primary flaw is that there can be only one. If you are okay with the non-composability then you could also integrate a DB here with a single-phase database commit (just JDBC .commit()).

whileCommitting handlers run after commit is guaranteed but before the transaction's writes have become visible to other threads. They don't have the ability to roll the transaction back, however.

Can you describe a bit more about what you want to run in the handler?

Thanks,
  Nathan


--
 
 
 



--
Nathan Grasso Bronson
ngbr...@gmail.com

Andy

unread,
Jan 23, 2013, 4:04:55 PM1/23/13
to scala-stm-e...@googlegroups.com
Wow, thanks for the rapid response! Comments inline..

You guessed it. I need to do an atomic write ( just a single write of one event, no reads ) to an event log to record the transaction in case of  process / node / cluster failure. The most commonly used implementation of the of the event log is just a mysql db table so, it is just a single atomic insert. 

whileCommitting seems to be a good option because if the persistance throws an exception a full branch of an actor system will be killed and rebuilt off the event stream and the clients of the shared refs are all part of the same branch.

Does this make sense?

Thanks,
Andrew

Nathan Bronson

unread,
Jan 23, 2013, 4:25:23 PM1/23/13
to scala-stm-e...@googlegroups.com
Sounds reasonable. For reference, the default behavior if an exception is thrown from whileCommitting is to save the exception, finish the commit, and then rethrow the exception.

 - Nathan

Andy

unread,
Jan 23, 2013, 5:39:19 PM1/23/13
to scala-stm-e...@googlegroups.com
Great. I have a test that can reproduce a race condition we run into when we save our event in afterCommit. Ill change to whileCommitting and rerun our test. Ill post the results.

Thanks,
Andrew
Reply all
Reply to author
Forward
0 new messages