[jboss-dev-forums] [Design of JBoss Transaction Services] - Re: JBAS-5801 - Locking in 2PC

adrian@jboss.org do-not-reply at jboss.com
Mon Jul 28 07:18:04 EDT 2008


"jhalliday" wrote : > What we really want to do is make sure that end() blocks
  | > at tx timeout until the current user operation has completed.
  | 
  | I'd argue that's exactly what we want to avoid. One use of a tx timeout is to ensure apps don't get stuck due to e.g. slow db queries. If I issue e.g. a SELECT inside a tx and that tx has a timeout, I want it to timeout promptly, not block on the db operation. Likewise for sending or receiving messages. That's part of the reason JBossTS uses a background thread for timeouts.  Sure some resource managers have explicit support for configuring timeouts on potentially long running operations, but it's not required.
  | 

It doesn't have to block indefinetly, the wait is configurable, 

  | <!-- Whether to use try locks in seconds
  | 
  |      The default is wait for a lock indefinitely
  |      e.g. 5 minutes
  |      <use-try-lock>300</use-try-lock>
  | -->
  | <!ELEMENT use-try-lock (#PCDATA)>
  | 

but the important thing is that they
don't go the wrong way around during normal operation otherwise 
you end up leaking the work into the "next/no transaction" without error, e.g.

Thread 1: does sql executeUpdate();
// Here Thread 1 hits (or more accurately is just about to hit) 
// the real jdbc connection, e.g. oracle code which we don't control
Thread 2: tx timeout
Thread 2: end() and rollback()
Thread 1: continues with update but now outside the transaction we initially intended

anonymous wrote : 
  | I'd say it's up to the resource manager's driver code to decide how to handle the situation. If it's got one thread doing a business logic operation in a tx when another thread is trying to terminate that tx, it can either block internally (I've seen the MS SQL driver do that, queuing the end to go over the same TCP/IP connection when the SELECT eventually returns) or e.g. throw an exception on the business logic thread.
  | 

For jdbc the correct thing to do is statement.cancel()
although that's not necessarily guaranteed to work depending upon the jdbc driver
and only for calls to the driver are that statement executes.

anonymous wrote : 
  | That said, one option may be to make this configurable at the JCA level. Allow e.g. -ds.xml files to contain an option for how the JCA should behave - delegate to the driver
  | 

We can't do that see the example above. Not because the driver
doesn't do its own locking (it probably does) but because it
might not understand the required semantics, e.g.

session.sendMessage(); // context switched before it actually does it
xaresource.rollback();
session,sendMessage() // really executes, but now outside the rolled back transaction

anonymous wrote : 
  |  as I describe, block as you suggest, 
  | or even explicitly interrupt the business logic and throw an exception as some users seem to expect. The last one of course is risky, it may mess up the underlying driver.

That's the mechanism of the previous TM.
In fact, what it did besides "interrupting the thread" was effectively
destroy the connection (if the I/O was on the same thread and it was in really in I/O)
meaning the connection got closed so you couldn't leak into the next/non
transaction.

Maybe that is an alternate option?

i.e. whenever we have a tx timeout, you provide a callback to JCA
and then we close the associated connections - disallowing their use
which may not be in a well defined state.

We could do this on a per connection-factory case depending upon
how well we know the underlying thirdparty code handles asynch rollbacks
concurrently with normal requests.

But my criticism of this is that the connection.close() is still
racing with the normal operation outside the intended transaction
so it could still complete before we close the connection to "cancel it".

Of course, if we closed the connections before the  now unnecessary rollback() 
then this wouldn't be a problem. ;-)

BACK ON TOPIC:
You didn't answer my question (even though I think I already know the answer :-)
which is that we only need to protect the end() invoked by the TM
to avoid the race, not the XAResource commit/rollback.
Which would mean the transaction interleaving problem of 5801 is easier to solve.

View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4166952#4166952

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4166952



More information about the jboss-dev-forums mailing list