db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Mike Matrigali (JIRA)" <j...@apache.org>
Subject [jira] Updated: (DERBY-3980) Conflicting select then update with REPEATABLE_READ gives lock timeout instead of deadlock
Date Thu, 11 Dec 2008 22:24:44 GMT

     [ https://issues.apache.org/jira/browse/DERBY-3980?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]

Mike Matrigali updated DERBY-3980:
----------------------------------


I've stared at the code below and am not clear what it is trying to do.  Main questions are
is it just trying to catch self waits?
and why is canSkip useful to call, what is the code counting on canSkip to tell it?

The case in question, posed as the below comment is:
Granted T0(S), T1(S), T0(U)
Waiting T0(X)
Waiting T1(U)

What is the expected value of canSkip for the 2 waiting locks.  Looking at the code I think
both are going to have canSkip
set to true to indicate that it is ok to grant them in front of other waiting locks, because
the space already holds a lock that
is blocking the waiting locks - but only if they are compatible with all other space granted
locks.

                if (index != -1) {

                    // We could be seeing a situation here like
                    // Granted T1{S}, T2{S}
                    // Waiting T1{X} - deadlock checking on this
                    //
                    // In this case it's not a deadlock, although it
                    // depends on the locking policy of the Lockable. E.g.
                    // Granted T1(latch)
                    // Waiting T1(latch)
                    //  is a deadlock.
                    //

                    if ((index == (chain.size() - 1)) ||
                        ((index == (chain.size() - 2))
                        && (index == (chain.indexOf(grants) - 1)))) {

                        // potential self deadlock, but probably not!
                        ActiveLock lock = (ActiveLock) waiters.get(space);

                        if (lock.canSkip) {
                            // not a deadlock ...
                            chain.push(space); // set up as rollback() expects.

                            rollback(chain);
                            continue outer;
                        }
                    }

                    return Deadlock.handle(factory, chain, index, waiters, deadl

> Conflicting select then update with REPEATABLE_READ gives lock timeout instead of deadlock
> ------------------------------------------------------------------------------------------
>
>                 Key: DERBY-3980
>                 URL: https://issues.apache.org/jira/browse/DERBY-3980
>             Project: Derby
>          Issue Type: Bug
>          Components: Store
>    Affects Versions: 10.1.3.1, 10.2.2.0, 10.3.3.0, 10.4.2.0, 10.5.0.0
>            Reporter: Kathey Marsden
>         Attachments: derby.log, derby.log.10_1, javacore.20081209.092827.9800.txt, TryTimeout.java,
TryTimeout2.java, TryTimeout2.out.10_1.deadlock, TryTimeout2.out.10_1.deadlock, TryTimeout2.out.10_1.locktimeout,
TryTimeout2.out.10_1.locktimeout
>
>
> The attached program TryTimeout.java should detect a deadlock but instead throws a lock
timeout exception.  The program has two threads that attempt:
> 	    
> 	    threadConnection.setAutoCommit(false);
> 	    /* set isolation level to repeatable read */
> 	    threadConnection.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
> 	    
> 	    ResultSet rs = stmt.executeQuery("select * from t where i = 456");
> 	    while (rs.next());
> 	    stmt.executeUpdate("update t set i = 456 where i = 456");
> 	    threadConnection.commit();
> This gives SQLState 40001 (deadlock) with DB2 but a lock timeout with Derby.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


Mime
View raw message