Derby
  1. Derby
  2. DERBY-5024

Document the behavior of interrupt handling.

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 10.8.1.2
    • Fix Version/s: 10.8.1.2
    • Component/s: Documentation
    • Labels:
      None

      Description

      DERBY-4741 improves Derby's handling of interrupts. Now the engine
      does not fall over when an interrupt occurs. Instead, Derby only kills
      the connection which is running when the interrupt happens, which may
      also be useful to stop execution in certain situations. Other times
      the connection will survive, i.e. the interrupt is ignored by Derby,
      although the interrupt status flag is kept. The exact behavior has
      been discussed on DERBY-4741 from 2011-02-10 onward.

      1. DERBY-5024.diff
        4 kB
        Kim Haase
      2. cdevdvlp22619.html
        8 kB
        Kim Haase
      3. cdevdvlp22619.html
        8 kB
        Kim Haase
      4. DERBY-5042-2.diff
        4 kB
        Kim Haase
      5. DERBY-5024-2.diff
        4 kB
        Kim Haase

        Issue Links

          Activity

          Hide
          Kim Haase added a comment -

          I've read the functional spec for DERBY-4741, but I'm still a bit confused about what has changed from the user's point of view.

          I'm guessing the topic "Working with database threads in an embedded environment" needs to be changed (http://db.apache.org/derby/docs/dev/devguide/devguide-single.html#cdevdvlp22619), but I'm not sure exactly how.

          Can you now use interrupt, as well as wait and notify, to notify threads that are accessing a database in an embedded environment? With the proviso that on Solaris you cannot do this on JDK 1.4, and on JDK 5 and 6 you can do it only if you run java with the option "-XX:-UseVMInterruptibleIO"?

          Will an interrupt close the database connection [but not cause Derby to shut down] if this can be done safely, but will otherwise be ignored?

          Thanks for any guidance.

          Show
          Kim Haase added a comment - I've read the functional spec for DERBY-4741 , but I'm still a bit confused about what has changed from the user's point of view. I'm guessing the topic "Working with database threads in an embedded environment" needs to be changed ( http://db.apache.org/derby/docs/dev/devguide/devguide-single.html#cdevdvlp22619 ), but I'm not sure exactly how. Can you now use interrupt, as well as wait and notify, to notify threads that are accessing a database in an embedded environment? With the proviso that on Solaris you cannot do this on JDK 1.4, and on JDK 5 and 6 you can do it only if you run java with the option "-XX:-UseVMInterruptibleIO"? Will an interrupt close the database connection [but not cause Derby to shut down] if this can be done safely, but will otherwise be ignored? Thanks for any guidance.
          Hide
          Rick Hillegas added a comment -

          Hi Kim,

          I recommend reading the conversation which Dag and I had about user-visible behavior. Take a look at our commentary on DERBY-4741. In particular, look at my last comment on 2011-02-10 and Dag's response on 2011-02-11. Thanks.

          Show
          Rick Hillegas added a comment - Hi Kim, I recommend reading the conversation which Dag and I had about user-visible behavior. Take a look at our commentary on DERBY-4741 . In particular, look at my last comment on 2011-02-10 and Dag's response on 2011-02-11. Thanks.
          Hide
          Kim Haase added a comment -

          Thanks, Rick – that helps, since DERBY-4741 is a large and daunting JIRA.

          One question for starters:

          "If a Thread is interrupted and the flag is not cleared" ...

          What flag is that? Is this the "interrupted status" that is tested by interrupted() and isInterrupted() but is otherwise not accessible programmatically?

          Show
          Kim Haase added a comment - Thanks, Rick – that helps, since DERBY-4741 is a large and daunting JIRA. One question for starters: "If a Thread is interrupted and the flag is not cleared" ... What flag is that? Is this the "interrupted status" that is tested by interrupted() and isInterrupted() but is otherwise not accessible programmatically?
          Hide
          Rick Hillegas added a comment -

          Hi Kim,

          Yes, that's the one. Thanks.

          Show
          Rick Hillegas added a comment - Hi Kim, Yes, that's the one. Thanks.
          Hide
          Kim Haase added a comment -

          Attaching DERBY-5024.diff and cdevdvlp22619.html, with changes to the topic "Working with database threads in an embedded environment". I hope I've disentangled all the information about the new behavior without too many errors. Please let me know what changes are needed.

          Show
          Kim Haase added a comment - Attaching DERBY-5024 .diff and cdevdvlp22619.html, with changes to the topic "Working with database threads in an embedded environment". I hope I've disentangled all the information about the new behavior without too many errors. Please let me know what changes are needed.
          Hide
          Dag H. Wanvik added a comment -

          Thanks for tacking this one, Kim! Some suggestions below inlined:

          > WORKING WITH DATABASE THREADS IN AN EMBEDDED ENVIRONMENT
          >
          > Do not use interrupt calls to notify java.lang.Thread objects that
          > are accessing a database, because Derby may catch the interrupt call
          > and close the connection to the database. Use wait and notify calls
          > instead.

          Suggest improvement of this sentence:

          "Do not normally use Thread#interrupt to signal possibly waiting
          threads that are also accessing a database because Derby may catch the
          interrupt and close the connection to the database. Use wait and
          notify calls instead."

          > This will not happen in a client/server environment, but if you want
          > your application to work in either environment it is good practice
          > to follow this rule.

          <... removed paragraph, see below>

          > There are also special considerations when working with more than
          > one database thread in an application, as described in Working with
          > multiple threads sharing a single connection.

          Move next paragraph to #4:

          > When queries, batches, and statements that wait for database locks
          > run longer than expected, you can use interrupts to stop them. If
          > you do, the Connection will be closed and an exception will be
          > thrown.

          "Connection" -> "connection" throughout, unless referring to the
          actual class java.sql.Connection

          > If you design an application that experiences Thread interrupts, you

          suggest:

          "If you design an application whose database threads may see
          interrupts, you"

          > should plan for the following behavior:
          >
          > * If a Thread is interrupted and the interrupt status flag is

          "Thread" -> "thread" throughout, unless referring to the actual class java.lang.Thread.

          > not cleared before entering a Derby JDBC call, or if the
          > Thread is interrupted while inside a Derby JDBC call, the
          > Connection that is experiencing the interrupt will be
          > terminated in the following situations:

          > o If a query fetches rows from a database table after the interrupt has occurred
          > o If the execution of a new element in a batched statement is attempted after the interrupt has occurred
          > o If an interrupt is received while a transaction is waiting for a lock
          >
          > If the Connection is terminated, the application will experience the following consequences:

          "application" -> "application thread"

          > o The JDBC call will raise an 08000 exception
          > ("Connection closed by unknown interrupt").

          "an 08000 exception" -> an SQLException with state "08000"

          > o Outstanding transactional work on that Connection will be rolled back, and all of its locks will be released.
          > o The Connection will not execute any further JDBC calls.

          "will not" -> "can not be used to"

          >
          > On return from the interrupted JDBC call, the isInterrupted() method of the Thread will return true, whether the Connection has been terminated or not.

          suggest:

          "On return from the JDBC call, Thread#isInterrupted will return
          true, whether an exception was thrown terminating the connection, or
          not. That is, even if Derby doesn't heed an interrupt, the flag will
          remain set on exit from the JDBC call."

          > All other Connections will remain active. This includes other

          "active" -> "open" above and below.

          > Connections which the interrupted Thread may be using.

          > These Connections will remain active at least until the Thread,
          > still with its interrupted status set, tries to use another
          > connection, in which case this Connection is also subject to
          > termination.

          suggest:

          These connections will remain open at least until the thread tries to
          use another of its other connections. If the thead has neglected to
          clear its interrupted flag, this connection is also subject to
          termination as described above.

          > The application should catch the 08000 exceptions, discard the
          > dead Connection, clear the interrupted status of the Thread, and
          > then restart the transaction in a new Connection.

          "should" -> "should normally be prepared to"

          Show
          Dag H. Wanvik added a comment - Thanks for tacking this one, Kim! Some suggestions below inlined: > WORKING WITH DATABASE THREADS IN AN EMBEDDED ENVIRONMENT > > Do not use interrupt calls to notify java.lang.Thread objects that > are accessing a database, because Derby may catch the interrupt call > and close the connection to the database. Use wait and notify calls > instead. Suggest improvement of this sentence: "Do not normally use Thread#interrupt to signal possibly waiting threads that are also accessing a database because Derby may catch the interrupt and close the connection to the database. Use wait and notify calls instead." > This will not happen in a client/server environment, but if you want > your application to work in either environment it is good practice > to follow this rule. <... removed paragraph, see below> > There are also special considerations when working with more than > one database thread in an application, as described in Working with > multiple threads sharing a single connection. Move next paragraph to #4: > When queries, batches, and statements that wait for database locks > run longer than expected, you can use interrupts to stop them. If > you do, the Connection will be closed and an exception will be > thrown. "Connection" -> "connection" throughout, unless referring to the actual class java.sql.Connection > If you design an application that experiences Thread interrupts, you suggest: "If you design an application whose database threads may see interrupts, you" > should plan for the following behavior: > > * If a Thread is interrupted and the interrupt status flag is "Thread" -> "thread" throughout, unless referring to the actual class java.lang.Thread. > not cleared before entering a Derby JDBC call, or if the > Thread is interrupted while inside a Derby JDBC call, the > Connection that is experiencing the interrupt will be > terminated in the following situations: > o If a query fetches rows from a database table after the interrupt has occurred > o If the execution of a new element in a batched statement is attempted after the interrupt has occurred > o If an interrupt is received while a transaction is waiting for a lock > > If the Connection is terminated, the application will experience the following consequences: "application" -> "application thread" > o The JDBC call will raise an 08000 exception > ("Connection closed by unknown interrupt"). "an 08000 exception" -> an SQLException with state "08000" > o Outstanding transactional work on that Connection will be rolled back, and all of its locks will be released. > o The Connection will not execute any further JDBC calls. "will not" -> "can not be used to" > > On return from the interrupted JDBC call, the isInterrupted() method of the Thread will return true, whether the Connection has been terminated or not. suggest: "On return from the JDBC call, Thread#isInterrupted will return true, whether an exception was thrown terminating the connection, or not. That is, even if Derby doesn't heed an interrupt, the flag will remain set on exit from the JDBC call." > All other Connections will remain active. This includes other "active" -> "open" above and below. > Connections which the interrupted Thread may be using. > These Connections will remain active at least until the Thread, > still with its interrupted status set, tries to use another > connection, in which case this Connection is also subject to > termination. suggest: These connections will remain open at least until the thread tries to use another of its other connections. If the thead has neglected to clear its interrupted flag, this connection is also subject to termination as described above. > The application should catch the 08000 exceptions, discard the > dead Connection, clear the interrupted status of the Thread, and > then restart the transaction in a new Connection. "should" -> "should normally be prepared to"
          Hide
          Kim Haase added a comment -

          Thanks, Dag! I'm attaching DERBY-5042-2.diff and cdevdvlp22619.html, which I hope make the changes you asked for. I made a few language changes.

          There is one question in my mind about this first change:

          "Do not normally use Thread#interrupt to signal possibly waiting threads ..."

          When, instead of a blanket prohibition, we say you shouldn't normally do something, it raises the question, under what circumstances would you do it? I don't think we answer that question. Should we?

          (BTW, I changed "normally" to "As a rule" and put it at the beginning – more common usage.)

          Show
          Kim Haase added a comment - Thanks, Dag! I'm attaching DERBY-5042 -2.diff and cdevdvlp22619.html, which I hope make the changes you asked for. I made a few language changes. There is one question in my mind about this first change: "Do not normally use Thread#interrupt to signal possibly waiting threads ..." When, instead of a blanket prohibition, we say you shouldn't normally do something, it raises the question, under what circumstances would you do it? I don't think we answer that question. Should we? (BTW, I changed "normally" to "As a rule" and put it at the beginning – more common usage.)
          Hide
          Kim Haase added a comment -

          Oops, I meant DERBY-5024-2.diff.

          Show
          Kim Haase added a comment - Oops, I meant DERBY-5024 -2.diff.
          Hide
          Dag H. Wanvik added a comment -

          Thanks, Kim! The exception here is when one actually intends to kill the connection by an interrupt, presumably because it is taking too long.
          I think pre-existing wording here refers to a practice of releasing waiting threads waiting on an arbitrary monitor (threads which are also sometimes doing embedded Derby calls), by interrupting them instead of Object#notify. When a thread calls Object#wait, it can be released from that wait by a Object#notify or an interrupt. I think the existing wording in our docs warns against that practice for threads that also field Derby calls. If others have different interpretations if this, please speak up Cf also Javadoc http://download.oracle.com/javase/6/docs/api/java/lang/Object.html#wait().
          Presumably, the thread releasing the resource doesn't know for sure what the other (possibly waiting threads are doing).. Notify or NotifyAll is the correct idiom as a rule

          Show
          Dag H. Wanvik added a comment - Thanks, Kim! The exception here is when one actually intends to kill the connection by an interrupt, presumably because it is taking too long. I think pre-existing wording here refers to a practice of releasing waiting threads waiting on an arbitrary monitor (threads which are also sometimes doing embedded Derby calls), by interrupting them instead of Object#notify. When a thread calls Object#wait, it can be released from that wait by a Object#notify or an interrupt. I think the existing wording in our docs warns against that practice for threads that also field Derby calls. If others have different interpretations if this, please speak up Cf also Javadoc http://download.oracle.com/javase/6/docs/api/java/lang/Object.html#wait( ). Presumably, the thread releasing the resource doesn't know for sure what the other (possibly waiting threads are doing).. Notify or NotifyAll is the correct idiom as a rule
          Hide
          Dag H. Wanvik added a comment -

          Read version #2, it looks great now, Kim, thank you! Feel free to update it to further clarify, cf my answer to your question. I'm +1.

          Show
          Dag H. Wanvik added a comment - Read version #2, it looks great now, Kim, thank you! Feel free to update it to further clarify, cf my answer to your question. I'm +1.
          Hide
          Kim Haase added a comment -

          Thanks, Dag, for that information! I expect most readers will know more about threads than I do, so I have committed the patch you approved as is.

          Committed patch DERBY-5024-2.diff to documentation trunk at revision 1075954.

          Show
          Kim Haase added a comment - Thanks, Dag, for that information! I expect most readers will know more about threads than I do, so I have committed the patch you approved as is. Committed patch DERBY-5024 -2.diff to documentation trunk at revision 1075954.

            People

            • Assignee:
              Kim Haase
              Reporter:
              Rick Hillegas
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development