You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@commons.apache.org by Antranig Basman <an...@caret.cam.ac.uk> on 2004/11/11 19:16:53 UTC

[transaction] Locking

Oliver Zeigermann wrote:
> 
> > Another question - I'm looking over the locking strategy for FRM
> > and am keen that I can ensure it blocks rather than throwing
> 
> Yes, serializability (complicated word, hope the spelling is right) is
> guaranteed by locks. There are four lock level
> 0: none
> 1: request wide read outside of transactions
> 2: transaction wide read (shared)
> 3: transaction wide write (exclusive)
> 4: commit lock that prohibits all other locks on resources being committed

Thanks - could I just confim my understanding of this with you?
In my application some files store indexes of other resources - say
that transactions T1, T2 are attempting to add to this index 
concurrently. Each reads the resource before it writes it - is it
correct that their lock level 2 they take out on read is 
insufficient to protect against lost data once they try to write
back their updated versions of the index?
What I would like is that any read within a transaction prevents
any other read of this resource within any other transaction - 
I presume I will need to ensure this manually with a call to
lockResource(resourceId, txId, false)
before each transaction issues its read?
Or is even a lock level 3 not sufficient to cause reads 
within other transactions to block?
Essentially I would like to take out a lock of a type that
prevents reads by any other threads having this same type of lock,
but allows other reads to continue. What is the type of this lock? :P

> However, if a lock can not be acquired in the specified time the lock
> methods will throw exceptions. Currently, the file system can not tell
> a livelock from a deadlock. Both will just throw an exception...
> 
> > whenever possible. I notice that in lockResource() there is a call
> > to
> > assureNotMarkedForRollback(context);
> > which, by my best understanding, will throw if a prepareTransaction
> > has failed on the resource. Could you explain why this is necessary?
> 
> Yes, or if it has explicitely been marked for roll back by method
> markTransactionForRollback. The reason is to tell the user not to make
> any modifications to a transaction that will eventually fail anyway.
> However, you are right, this is not mandatory for correctness...
> 
> > To be sure, if one transaction has failed on modifying a resource,
> > it is quite likely that another will, and the time window for
> > observing this effect is only that between a prepare fail and an
> > exception handler being located for a rollback, but I'd like to
> > understand the reasoning behind it if I can.
> 
> Do not quite understand this. Could you explain a bit more, please?

I think the only point of confusion may be whether we are talking
about mark for rollback by a transaction for *this* thread or
by any other threads. If *this* thread is in the middle of a rollback
then it is quite right that a lock should throw, since this 
almost certainly represents a programming error... but then if the
author has screwed up exception handling to this extent they
probably will not listen to a further one :P On the other hand
failing a lock because *another* thread is rolling back seems
rather severe - I presume it is the former we are talking about?

Thanks,
Antranig.

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org


Re: [transaction] Locking

Posted by Oliver Zeigermann <ol...@gmail.com>.
On Fri, 12 Nov 2004 17:44:50 +0000, Antranig Basman
<an...@caret.cam.ac.uk> wrote:
> Oliver Zeigermann wrote:
> 
> 
> >
> > Sorry for causing confusion, these lock levels are just internal ones.
> > For you the
> >
> > public boolean lockResource(Object resourceId, Object txId, boolean
> > shared) throws ResourceManagerException
> >
> > method is the one to use. It will be called implicitely along with all
> > read/write requests as well. So, if you want an exclusive lock, just
> > set shared to false and there you go. This will be set to exclusive as
> > soon as a transaction starts to write as well.
> >
> > However, if you know even before reading that you will finally write,
> > it is a very good idea to get an exclusive lock right at the beginning
> > of a transaction. This decreases the likelyhood of a deadlock (to
> > almost zero)...
> 
> Yes - to be more clear, in my application I do not want to exclude
> non-writing readers from reading in this case. I only want to exclude
> writing ones - from what you are saying I cannot achieve these
> semantics with the current LockManager implementation?

This is possible when doing read requests outside of a transaction using 

public InputStream readResource(Object resourceId) throws
ResourceManagerException;

Reads and writes inside of another transaction would be disallowed,
though. It is important to disallow reads in other transactions as
otherwise various spurious and unwanted effects like e.g. lost updates
might occur...

 
> > If you have a threaded application I highly recommend to associate a
> > thread to exactly one transaction. Just use the thread itself as the
> > transaction id. If so, there will be at most one thread that can mark
> > a transaction for rollback.
> 
> Yes - I actually have a TransactionThreadMap for this purpose and
> at my higher API level transaction IDs do not appear as method
> arguments. Perhaps I might contribute it so you can save a
> few (one?) methods in your FileResourceManager? :P
> I have also made a "NestedTransactionWrapper" that uses this class
> to provide nested transaction semantics to users. Trouble is these
> have dependency on my "UniversalRuntimeException"
> scheme for avoidance of checked exceptions wherever possible...

I see, this is the usual way of doing this - 1:1 mappings of
transactions to threads. The JTS does this as well and maybe I should
have done this with the transactional file system?! But I guess a
layer based upon it as you described might be sufficient.

How does you nestted transaction wrapper look like? How does it work?
Interesting...

> 
> 
> > > If *this* thread is in the middle of a rollback
> > > then it is quite right that a lock should throw, since this
> > > almost certainly represents a programming error... but then if the
> > > author has screwed up exception handling to this extent they
> > > probably will not listen to a further one :P On the other hand
> > > failing a lock because *another* thread is rolling back seems
> > > rather severe - I presume it is the former we are talking about?
> >
> > Hmmm, I am afraid I still do not understand you completely. Usually,
> > the idea of using transactions includes that each transaction should
> > have the "impression" that there are no other transactions...
> >
> > Maybe we do not use the same terminology: What is your understanding
> > of a transaction and a rollback of a transaction and what is your idea
> > of locking a resouce?
> 
> I think our terminology agrees. Since transactions should have the
> impression that no other transactions are in force, what you are
> telling me implicitly is that the answer to my question is that
> assureLock() will only throw if *this* thread is in a transaction
> that is rolling back, ignoring the state of any others. Could you
> just briefly confirm this? :P

Yes, exactly, sorry for making this for complicated than necessary.

Looking forward to see more of your work! May I ask what kind of
application you are building?

Oliver

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org


Re: [transaction] Locking

Posted by Antranig Basman <an...@caret.cam.ac.uk>.
Oliver Zeigermann wrote:
>
> Sorry for causing confusion, these lock levels are just internal ones.
> For you the
> 
> public boolean lockResource(Object resourceId, Object txId, boolean
> shared) throws ResourceManagerException
> 
> method is the one to use. It will be called implicitely along with all
> read/write requests as well. So, if you want an exclusive lock, just
> set shared to false and there you go. This will be set to exclusive as
> soon as a transaction starts to write as well.
> 
> However, if you know even before reading that you will finally write,
> it is a very good idea to get an exclusive lock right at the beginning
> of a transaction. This decreases the likelyhood of a deadlock (to
> almost zero)...

Yes - to be more clear, in my application I do not want to exclude
non-writing readers from reading in this case. I only want to exclude
writing ones - from what you are saying I cannot achieve these 
semantics with the current LockManager implementation?

> If you have a threaded application I highly recommend to associate a
> thread to exactly one transaction. Just use the thread itself as the
> transaction id. If so, there will be at most one thread that can mark
> a transaction for rollback.

Yes - I actually have a TransactionThreadMap for this purpose and 
at my higher API level transaction IDs do not appear as method
arguments. Perhaps I might contribute it so you can save a 
few (one?) methods in your FileResourceManager? :P
I have also made a "NestedTransactionWrapper" that uses this class
to provide nested transaction semantics to users. Trouble is these
have dependency on my "UniversalRuntimeException"
scheme for avoidance of checked exceptions wherever possible...

> > If *this* thread is in the middle of a rollback
> > then it is quite right that a lock should throw, since this
> > almost certainly represents a programming error... but then if the
> > author has screwed up exception handling to this extent they
> > probably will not listen to a further one :P On the other hand
> > failing a lock because *another* thread is rolling back seems
> > rather severe - I presume it is the former we are talking about?
> 
> Hmmm, I am afraid I still do not understand you completely. Usually,
> the idea of using transactions includes that each transaction should
> have the "impression" that there are no other transactions...
> 
> Maybe we do not use the same terminology: What is your understanding
> of a transaction and a rollback of a transaction and what is your idea
> of locking a resouce?

I think our terminology agrees. Since transactions should have the
impression that no other transactions are in force, what you are 
telling me implicitly is that the answer to my question is that
assureLock() will only throw if *this* thread is in a transaction
that is rolling back, ignoring the state of any others. Could you
just briefly confirm this? :P

Thanks,
Antranig.

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org


Re: [transaction] Locking

Posted by Oliver Zeigermann <ol...@gmail.com>.
On Thu, 11 Nov 2004 18:16:53 +0000, Antranig Basman
<an...@caret.cam.ac.uk> wrote:
> Oliver Zeigermann wrote:
> >
> > > Another question - I'm looking over the locking strategy for FRM
> > > and am keen that I can ensure it blocks rather than throwing
> >
> > Yes, serializability (complicated word, hope the spelling is right) is
> > guaranteed by locks. There are four lock level
> > 0: none
> > 1: request wide read outside of transactions
> > 2: transaction wide read (shared)
> > 3: transaction wide write (exclusive)
> > 4: commit lock that prohibits all other locks on resources being committed
> 
> Thanks - could I just confim my understanding of this with you?
> In my application some files store indexes of other resources - say
> that transactions T1, T2 are attempting to add to this index
> concurrently. Each reads the resource before it writes it - is it
> correct that their lock level 2 they take out on read is
> insufficient to protect against lost data once they try to write
> back their updated versions of the index?
> What I would like is that any read within a transaction prevents
> any other read of this resource within any other transaction -
> I presume I will need to ensure this manually with a call to
> lockResource(resourceId, txId, false)
> before each transaction issues its read?
> Or is even a lock level 3 not sufficient to cause reads
> within other transactions to block?
> Essentially I would like to take out a lock of a type that
> prevents reads by any other threads having this same type of lock,
> but allows other reads to continue. What is the type of this lock? :P

Sorry for causing confusion, these lock levels are just internal ones.
For you the

public boolean lockResource(Object resourceId, Object txId, boolean
shared) throws ResourceManagerException

method is the one to use. It will be called implicitely along with all
read/write requests as well. So, if you want an exclusive lock, just
set shared to false and there you go. This will be set to exclusive as
soon as a transaction starts to write as well.

However, if you know even before reading that you will finally write,
it is a very good idea to get an exclusive lock right at the beginning
of a transaction. This decreases the likelyhood of a deadlock (to
almost zero)...

 > > However, if a lock can not be acquired in the specified time the lock
> > methods will throw exceptions. Currently, the file system can not tell
> > a livelock from a deadlock. Both will just throw an exception...
> >
> > > whenever possible. I notice that in lockResource() there is a call
> > > to
> > > assureNotMarkedForRollback(context);
> > > which, by my best understanding, will throw if a prepareTransaction
> > > has failed on the resource. Could you explain why this is necessary?
> >
> > Yes, or if it has explicitely been marked for roll back by method
> > markTransactionForRollback. The reason is to tell the user not to make
> > any modifications to a transaction that will eventually fail anyway.
> > However, you are right, this is not mandatory for correctness...
> >
> > > To be sure, if one transaction has failed on modifying a resource,
> > > it is quite likely that another will, and the time window for
> > > observing this effect is only that between a prepare fail and an
> > > exception handler being located for a rollback, but I'd like to
> > > understand the reasoning behind it if I can.
> >
> > Do not quite understand this. Could you explain a bit more, please?
> 
> I think the only point of confusion may be whether we are talking
> about mark for rollback by a transaction for *this* thread or
> by any other threads. 

If you have a threaded application I highly recommend to associate a
thread to exactly one transaction. Just use the thread itself as the
transaction id. If so, there will be at most one thread that can mark
a transaction for rollback.

> If *this* thread is in the middle of a rollback
> then it is quite right that a lock should throw, since this
> almost certainly represents a programming error... but then if the
> author has screwed up exception handling to this extent they
> probably will not listen to a further one :P On the other hand
> failing a lock because *another* thread is rolling back seems
> rather severe - I presume it is the former we are talking about?

Hmmm, I am afraid I still do not understand you completely. Usually,
the idea of using transactions includes that each transaction should
have the "impression" that there are no other transactions...

Maybe we do not use the same terminology: What is your understanding
of a transaction and a rollback of a transaction and what is your idea
of locking a resouce?

I am pretty sure once we get definitions aligned, we can settle this quickly...

Oliver

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org