[concurrency-interest] Concurrency-interest Digest, Vol 87, Issue 27

Gregg Wonderly gregg at cytetech.com
Tue Apr 17 09:31:55 EDT 2012

On 4/16/2012 2:53 PM, Khilan Gudka wrote:
> While it is true that using explicit locks gives you more flexibility, i think a
> distinction needs to be made here between preventing deadlock from occurring but
> it being too late to rectify things (your approach if am not mistaken) versus
> not ever reaching a situation where deadlock could even be detected (gadara).
> The former is obviously useful because at least it means your system cannot
> hang, but then the next question is how does the system continue when you have
> detected deadlock? In particular, if you have to release multiple locks, how do
> you rollback side effects that have been made in the mean-time?

The most obvious way to accomplish this, is to use transactional behaviors so 
that at any level, permanent changes in state can be reverted to a "safe" form 
by causing a transaction or transactional-like rollback.

In Java, the Jini (now Apache River) platform provides a distributed transaction 
service which makes it possible to do this relatively easily.  In JavaEE 
applications, there is, of course, transactions already available for "database" 
kinds of transactions.

It requires a more deliberate software failure design focus, but that is what 
Jini has been about all along.  In a "distributed" (at the thread, process or 
machine level) system, partial failure must be dealt with effectively.

Transactional behaviors are what makes the most sense, but you need to be able 
to do the "rollback" without acquiring any additional locks.  Code blocks such 
as the following,

FileInputStream fs = new FileInputStream( inFile );
try {
	inputRead = true;
} catch( IOException ex ) {
	reportIOExceptionOnFile( ex, inFile );
	return false;
} catch( RuntimeException ex ) {
	reportProcessingException( ex, inFile );
	return false;
} finally {
return true;

have transactional behaviors because they indicate the progress made, 
definitively, so that your application can "recoup" after an unexpected
error (return false;) and be ready to try again with no "hung state".

Using Jini transactions, I've written applications which keep multiple instances 
of postgres databases in sync.  The use of Jini leasing also lets you monitor 
progress, and use another thread to "cancel" a transaction so that lack of 
progress can be overted, appropriately.

Gregg Wonderly

More information about the Concurrency-interest mailing list