[
https://issues.apache.org/jira/browse/DERBY-4741?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12923955#action_12923955
]
Dag H. Wanvik edited comment on DERBY-4741 at 10/22/10 2:28 PM:
----------------------------------------------------------------
Uploading a first rev of a patch for part a):
derby-4741-a-01-api-interruptstatus
Regressions ran ok modulo a hang in BootLockTest.
This patch contains the new helper class InterruptStatus and inserts calls to
restoreIntrFlagIfSeen in before API methods' return and in the exception
handling (TransactionResourceImpl#handleException).
Execution of EmbedStatement#executeBatch check of interrupts and throws 08000
if seen between each statement in the batch.
Note: Still, the machinery of InterruptStatus isn't used to save any
interrupts, that follows in a later patch, so this patch doesn't change
behavior. The focus here is on the correct placement of calls to
restoreIntrFlagIfSeen in the API. Reviews appreciated!
------------------------ Patch details:
- iapi.util.InterruptStatus: new helper class for keeping track of detected and
postponed interrupts. See also its Javadoc.
- LanguageConnectionContext
GenericLanguageConnectionContext:
Methods to set/reset threads interrupt status flag to allow us to clear the
thread's actual flag temporarily, and to reset it when we return to the user
application, possibly by throwing an interrupted SQLException (SQL state 08000)
if we cut something short. It also contains methods to save and retrieve the
stack frame at the point an interrupt was detected. This is used when we throw
the interrupt exception.
- TransactionResourceImpl: resurrect the thread's interrupt status flag on SQL
error (called from handleException). Use lcc if available, else thread local
variable.
- EmbedBlob, for methods that call handleException inside synchronized on
connection: use InterruptStatus.restoreIntrFlagIfSeen(lcc) before return
- EmbedResultSet: for methods that call handleException inside synchronized on
connection: use InterruptStatus.restoreIntrFlagIfSeen(lcc) before return
- EmbedStatment: for methods that call handleException inside synchronized on
connection: use InterruptStatus.restoreIntrFlagIfSeen(lcc) before return
In executeBatch, use throwIf between each statement in the batch: if we saw
an interrupt, stop execution of batch. Note that if we do throw,
restoreIntrFlagIfSeen will be called in the finally block, but it is
idempotent, so no harm is done. It is necessary in case we saw an interrupt in
the last statement of the batch.
- EmbedDatabaseMetaData: for methods that call handleException inside
synchronized on connection: use InterruptStatus.restoreIntrFlagIfSeen(lcc)
before return
- EmbedPreparedStatement: for methods that call handleException inside
synchronized on connection: use InterruptStatus.restoreIntrFlagIfSeen(lcc)
before return
- EmbedConnection.java: for methods that call handleException inside
synchronized on connection: use InterruptStatus.restoreIntrFlagIfSeen(lcc)
before return
For createDatabase, use InterruptStatus.restoreIntrFlagIfSeen() which
inspects the thread local variable. This should catch I/O interrupts seen
during the database creation phase.
Special handling in #close to make sure we access lcc while it is still
available.
was (Author: dagw):
Uploading a first rev of a patch for part a):
derby-4741-a-01-api-interruptstatus
Regressions ran ok modulo a hang in BootLockTest.
This patch contains the new helper class InterruptStatus and inserts calls to
restoreIntrFlagIfSeen in before API methods' return and in the exception
handling (TransactionResourceImpl#handleException).
Execution of EmbedStatement#executeBatch check of interrupts and throws 08000
if seen between each statement in the batch.
Note: Still, the machinery of InterruptStatus isn't used to save any
interrupts, that follows in a later patch, so this patch doesn't change
behavior. The focus here is on the correct placement of calls to
restoreIntrFlagIfSeen in the API. Reviews appreciated!
------------------------ Patch details:
- iapi.util.InterruptStatus: new helper class for keeping track of detected and
postponed interrupts
- LanguageConnectionContext
GenericLanguageConnectionContext:
Methods to set/reset threads interrupt status flag to allow us to clear the
thread's actual flag temporarily, and to reset it when we return to the user
application, possibly by throwing an interrupted SQLException (SQL state 08000)
if we cut something short. It also contains methods to save and retrieve the
stack frame at the point an interrupt was detected. This is used when we throw
the interrupt exception. See also its Javadoc.
- TransactionResourceImpl: resurrect the thread's interrupt status flag on SQL
error (called from handleException). Use lcc if available, else thread local
variable.
- EmbedBlob, for methods that call handleException inside synchronized on
connection: use InterruptStatus.restoreIntrFlagIfSeen(lcc) before return
- EmbedResultSet: for methods that call handleException inside synchronized on
connection: use InterruptStatus.restoreIntrFlagIfSeen(lcc) before return
- EmbedStatment: for methods that call handleException inside synchronized on
connection: use InterruptStatus.restoreIntrFlagIfSeen(lcc) before return
In executeBatch, use throwIf between each statement in the batch: if we saw
an interrupt, stop execution of batch. Note that if we do throw,
restoreIntrFlagIfSeen will be called in the finally block, but it is
idempotent, so no harm is done. It is necessary in case we saw an interrupt in
the last statement of the batch.
- EmbedDatabaseMetaData: for methods that call handleException inside
synchronized on connection: use InterruptStatus.restoreIntrFlagIfSeen(lcc)
before return
- EmbedPreparedStatement: for methods that call handleException inside
synchronized on connection: use InterruptStatus.restoreIntrFlagIfSeen(lcc)
before return
- EmbedConnection.java: for methods that call handleException inside
synchronized on connection: use InterruptStatus.restoreIntrFlagIfSeen(lcc)
before return
For createDatabase, use InterruptStatus.restoreIntrFlagIfSeen() which
inspects the thread local variable. This should catch I/O interrupts seen
during the database creation phase.
Special handling in #close to make sure we access lcc while it is still
available.
> Make Derby work reliably in the presence of thread interrupts
> -------------------------------------------------------------
>
> Key: DERBY-4741
> URL: https://issues.apache.org/jira/browse/DERBY-4741
> Project: Derby
> Issue Type: Bug
> Components: Store
> Affects Versions: 10.2.1.6, 10.2.2.0, 10.3.1.4, 10.3.2.1, 10.3.3.0,
> 10.4.1.3, 10.4.2.0, 10.5.1.1, 10.5.2.0, 10.5.3.0, 10.6.1.0
> Reporter: Dag H. Wanvik
> Assignee: Dag H. Wanvik
> Attachments: derby-4741-a-01-api-interruptstatus.diff,
> derby-4741-a-01-api-interruptstatus.stat,
> derby-4741-all+lenient+resurrect.diff, derby-4741-all+lenient+resurrect.stat,
> derby-4741-nio-container+log+waits+locks+throws.diff,
> derby-4741-nio-container+log+waits+locks+throws.stat,
> derby-4741-nio-container+log+waits+locks-2.diff,
> derby-4741-nio-container+log+waits+locks-2.stat,
> derby-4741-nio-container+log+waits+locks.diff,
> derby-4741-nio-container+log+waits+locks.stat,
> derby-4741-nio-container+log+waits.diff,
> derby-4741-nio-container+log+waits.stat, derby-4741-nio-container+log.diff,
> derby-4741-nio-container+log.stat, derby-4741-nio-container-2.diff,
> derby-4741-nio-container-2.log, derby-4741-nio-container-2.stat,
> derby-4741-nio-container-2b.diff, derby-4741-nio-container-2b.stat,
> derby.log, derby.log, MicroAPITest.java, xsbt0.log.gz
>
>
> When not executing on a small device VM, Derby has been using the Java NIO
> classes java.nio.clannel.* for file io.
> If thread is interrupted while executing blocking IO operations in NIO, the
> ClosedByInterruptException will get thrown. Unfortunately, Derby isn't
> current architected to retry and complete such operations (before passing on
> the interrupt), so the Derby database can be left in an inconsistent state
> and we therefore have to return a database level error. This means the
> applications can no longer access the database without a shutdown and reboot
> including a recovery.
> It would be nice if Derby could somehow detect and finish IO operations
> underway when thread interrupts happen before passing the exception on to the
> application. Derby embedded is sometimes embedded in applications that use
> Thread.interrupt to stop threads.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.