You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@directory.apache.org by Charles Lamb <cw...@sleepycat.com> on 2004/04/16 21:03:21 UTC

Re: [bdbje] Using a ThreadLocal to find a Transaction

Alex Karasulu wrote:

>It might be nice not to have to worry about providing the Transaction 
>which can be checked for by the JE method itself using the ThreadLocal.
>There is nothing stopping me from doing this myself in those classes 
>that make the calls to JE but I just thought I'd see if you guys 
>thought of it and if so why it's not used.  I'm sure the idea must 
>have occurred at some point.
>
Hi Alex,

Briefly, this is a good idea.

More details.

If you use the Collections API, there is already the notion of a current 
transaction.

If you use the "base API" (which I think you're doing), there is no such 
notion of current transaction as you correctly point out.  Certainly 
using ThreadLocal is an option and I'm going to think carefully about 
that.  One thing that comes to mind is how we specify to use ThreadLocal 
in the API.  Currently, passing null as the txn parameter means Auto 
Commit.  We could theoretically overload the null txn parameter to mean 
"use a threadlocal if it's there [i.e. previously specified through some 
other API call], and if not, then this call is AutoTxn".  There are, of 
course, issues in maintaining compatibility with the BDB API.

Thanks for your feedback.

Charles Lamb




Re: [bdbje] Using a ThreadLocal to find a Transaction

Posted by Mark Hayes <ma...@sleepycat.com>.
On Apr 16, 2004, at 12:03 PM, Charles Lamb wrote:
>
> If you use the Collections API, there is already the notion of a 
> current transaction.

You could say there are two parts to the problem of providing a 
"current implicit transaction" that works with the JE API ("base API") 
level.

1- A ThreadLocal-based object is needed for storing the current 
transaction for the current thread.

2- An adapter API, or perhaps in the future the JE API itself, is 
needed that uses the current transaction rather than an explicit 
transaction parameter.

Part 2 is not provided in the current JE product.

However, part 1 is provided by the CurrentTransaction class in the 
com.sleepycat.collection package.  This class has beginTransaction, 
commitTransaction, and abortTransaction methods for managing the 
implicit transaction.  Its getTransaction method could be used by an 
adapter layer for getting the implicit transaction and passing it on to 
the base JE API.

The TransactionRunner class, also in the collections package, provides 
a higher level abstraction for running transactions, performing 
retries, and handling deadlocks.  TransactionRunner uses 
CurrentTransaction.

Both CurrentTransaction and TransactionRunner, while designed to be 
used with collections, are not dependent on collections and can be used 
with the base JE API.

Another thing to note is that CurrentTransaction is not a singleton but 
rather is scoped to a JE Environment object.  That way, more than one 
JE Environment can be open at the same time and each will have a 
different "current transaction" per thread.  The 
CurrentTransaction.getInstance(Environment) static method returns the 
instance for a given environment.

Also note is that a complete solution to this problem would provide a 
way to perform database reads without using the implicit transaction, 
in cases where obtaining a read lock is not desired.  In other words, 
just because there is an active transaction for the current thread 
doesn't necessarily mean that you want to use that transaction for 
reading.  For performance reasons you may not want to retain read locks 
for the duration of the entire transaction.

So, in the adapter layer you're discussing, you may want to provide a 
way to read without using the implicit transaction.  If Sleepycat were 
to support the implicit current transaction in the base JE API, I think 
we would want to provide a way to read outside of a transaction.

Passing LockMode.DIRTY_READ is a workaround for this problem, but is 
not a complete solution since you may want to read outside of a 
transaction but only read committed data.

Mark


RE: [bdbje] Using a ThreadLocal to find a Transaction

Posted by "Noel J. Bergman" <no...@devtech.com>.
Alex,

And if you get a transaction from the lower layer, perhaps it is the adapter
that stores the transaction in the thread local.  One issue you will need to
address is how this should work with thread pooling, since you are trying to
hide this whole notion from at least intermediate client layers.

	--- Noel


RE: [bdbje] Using a ThreadLocal to find a Transaction

Posted by Alex Karasulu <ao...@bellsouth.net>.
Yeah I agree completely.  That's most likely the direction I intend to 
take on this one.

Alex

> -----Original Message-----
> From: Noel J. Bergman [mailto:noel@devtech.com]
> Sent: Sunday, April 18, 2004 4:26 PM
> To: Apache Directory Developers List
> Cc: bdbje@sleepycat.com
> Subject: RE: [bdbje] Using a ThreadLocal to find a Transaction
> 
> > If you use the "base API" (which I think you're doing), there is no such
> > notion of current transaction as you correctly point out.  Certainly
> > using ThreadLocal is an option and I'm going to think carefully about
> > that.  One thing that comes to mind is how we specify to use ThreadLocal
> > in the API.  Currently, passing null as the txn parameter means Auto
> > Commit.
> 
> If your interface passes the transaction as a explicit parameter it would
> be
> easier to have an adapter (either in your code or client code) such that:
> 
>  a() -> set thread local
>         b()
>  b() -> c()
>  c() -> get thread local
>         d(..., transaction, ...)
> 
> The adapter layer would parallel the Base API without the explicit
> transaction parameter.
> 
> 	--- Noel




RE: [bdbje] Using a ThreadLocal to find a Transaction

Posted by "Noel J. Bergman" <no...@devtech.com>.
> If you use the "base API" (which I think you're doing), there is no such
> notion of current transaction as you correctly point out.  Certainly
> using ThreadLocal is an option and I'm going to think carefully about
> that.  One thing that comes to mind is how we specify to use ThreadLocal
> in the API.  Currently, passing null as the txn parameter means Auto
> Commit.

If your interface passes the transaction as a explicit parameter it would be
easier to have an adapter (either in your code or client code) such that:

 a() -> set thread local
        b()
 b() -> c()
 c() -> get thread local
        d(..., transaction, ...)

The adapter layer would parallel the Base API without the explicit
transaction parameter.

	--- Noel