You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by rh...@apache.org on 2014/05/10 15:55:50 UTC
svn commit: r1593702 - in /db/derby/code/trunk/java:
engine/org/apache/derby/iapi/error/
engine/org/apache/derby/iapi/services/locks/
engine/org/apache/derby/iapi/sql/dictionary/
engine/org/apache/derby/iapi/store/raw/ engine/org/apache/derby/iapi/stor...
Author: rhillegas
Date: Sat May 10 13:55:50 2014
New Revision: 1593702
URL: http://svn.apache.org/r1593702
Log:
DERBY-6554: Raise SelfDeadlock when a nested subtransaction can't immediately get a lock because it is blocked by its parent transaction; commit derby-6554-02-ae-selfDeadlock_sps_compress.diff.
Modified:
db/derby/code/trunk/java/engine/org/apache/derby/iapi/error/StandardException.java
db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/locks/LockOwner.java
db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/SPSDescriptor.java
db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/raw/RawStoreFactory.java
db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/raw/xact/TransactionFactory.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/ConcurrentLockSet.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/LockControl.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/UpdateLoader.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SequenceUpdater.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertResultSet.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/RAMTransaction.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/heap/HeapController.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/RawStore.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/InternalXact.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/Xact.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/XactFactory.java
db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SequenceTest.java
Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/error/StandardException.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/error/StandardException.java?rev=1593702&r1=1593701&r2=1593702&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/error/StandardException.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/error/StandardException.java Sat May 10 13:55:50 2014
@@ -658,6 +658,19 @@ public class StandardException extends E
}
/**
+ * Is this a self-deadlock exception caused by a nested transaction
+ * being blocked by its parent's locks.
+ * <p>
+ *
+ * @return true if this exception is a self-deadlock.
+ *
+ **/
+ public final boolean isSelfDeadlock() {
+
+ return(SQLState.SELF_DEADLOCK.equals(getSQLState()));
+ }
+
+ /**
* Is this a lock timeout or lock deadlock exception.
* <p>
*
Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/locks/LockOwner.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/locks/LockOwner.java?rev=1593702&r1=1593701&r2=1593702&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/locks/LockOwner.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/locks/LockOwner.java Sat May 10 13:55:50 2014
@@ -51,4 +51,20 @@ public interface LockOwner {
* {@code false} otherwise
*/
boolean noWait();
+
+
+ /**
+ * <p>
+ * Return true if this is a nested owner, e.g., a nested user transaction.
+ * </p>
+ */
+ public boolean isNestedOwner();
+
+ /**
+ * <p>
+ * Return true if this owner nests under another owner.
+ * </p>
+ */
+ public boolean nestsUnder( LockOwner other );
+
}
Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/SPSDescriptor.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/SPSDescriptor.java?rev=1593702&r1=1593701&r2=1593702&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/SPSDescriptor.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/SPSDescriptor.java Sat May 10 13:55:50 2014
@@ -750,7 +750,10 @@ public class SPSDescriptor extends Uniqu
nestedTC.rollbackToSavePoint(savepoint, false, null);
}
- if (nestedTC != null && se.isLockTimeout())
+ if (
+ (nestedTC != null) &&
+ ( se.isLockTimeout() || se.isSelfDeadlock() )
+ )
{
// Locks were set nowait, so a lock timeout here
// means that some lock request in the nested
Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/raw/RawStoreFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/raw/RawStoreFactory.java?rev=1593702&r1=1593701&r2=1593702&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/raw/RawStoreFactory.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/raw/RawStoreFactory.java Sat May 10 13:55:50 2014
@@ -660,6 +660,7 @@ public interface RawStoreFactory extends
context is popped off the stack.
</UL>
+ @param parentTransaction parent transaction
@param compatibilitySpace compatibility space to use for locks.
@param contextMgr is the context manager to use. An exception will be
thrown if context is not the current context.
@@ -674,6 +675,7 @@ public interface RawStoreFactory extends
*/
public Transaction startNestedReadOnlyUserTransaction(
+ Transaction parentTransaction,
CompatibilitySpace compatibilitySpace,
ContextManager contextMgr,
String transName)
@@ -720,6 +722,7 @@ public interface RawStoreFactory extends
context is popped off the stack.
</UL>
+ @param parentTransaction parent transaction
@param contextMgr is the context manager to use. An exception will be
thrown if context is not the current context.
@param transName is the name of the transaction. This name will be
@@ -737,6 +740,7 @@ public interface RawStoreFactory extends
*/
public Transaction startNestedUpdateUserTransaction(
+ Transaction parentTransaction,
ContextManager contextMgr,
String transName,
boolean flush_log_on_xact_end)
Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/raw/xact/TransactionFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/raw/xact/TransactionFactory.java?rev=1593702&r1=1593701&r2=1593702&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/raw/xact/TransactionFactory.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/raw/xact/TransactionFactory.java Sat May 10 13:55:50 2014
@@ -95,6 +95,8 @@ public interface TransactionFactory exte
method will push a transaction context as described in
RawStoreFactory.startNestedTransaction
+ @param rsf the RawStoreFactory
+ @param parentTransaction the parent transaction
@param compatibilitySpace compatibility space to use for locks.
@param contextMgr is the context manager to use. It must be
the current context manager.
@@ -107,6 +109,7 @@ public interface TransactionFactory exte
*/
public RawTransaction startNestedReadOnlyUserTransaction(
RawStoreFactory rsf,
+ RawTransaction parentTransaction,
CompatibilitySpace compatibilitySpace,
ContextManager contextMgr,
String transName)
@@ -117,6 +120,8 @@ public interface TransactionFactory exte
will push a transaction context as described in
RawStoreFactory.startNestedTransaction
+ @param rsf the RawStoreFactory
+ @param parentTransaction the parent transaction
@param contextMgr is the context manager to use. It must
be the current context manager.
@param transName is the transaction name. It will be
@@ -134,6 +139,7 @@ public interface TransactionFactory exte
*/
public RawTransaction startNestedUpdateUserTransaction(
RawStoreFactory rsf,
+ RawTransaction parentTransaction,
ContextManager contextMgr,
String transName,
boolean flush_log_on_xact_end)
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/ConcurrentLockSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/ConcurrentLockSet.java?rev=1593702&r1=1593701&r2=1593702&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/ConcurrentLockSet.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/ConcurrentLockSet.java Sat May 10 13:55:50 2014
@@ -319,6 +319,7 @@ final class ConcurrentLockSet implements
LockControl control;
Lock lockItem;
String lockDebug = null;
+ boolean blockedByParent = false;
Entry entry = getEntry(ref);
try {
@@ -355,12 +356,23 @@ final class ConcurrentLockSet implements
return lockItem;
}
- if (AbstractPool.noLockWait(timeout, compatibilitySpace)) {
-
+ //
+ // This logic supports the use-case of DERBY-6554.
+ //
+ blockedByParent =
+ (timeout == 0) &&
+ compatibilitySpace.getOwner().isNestedOwner() &&
+ control.blockedByParent( lockItem );
+
+ if (
+ AbstractPool.noLockWait(timeout, compatibilitySpace) ||
+ blockedByParent
+ )
+ {
// remove all trace of lock
control.giveUpWait(lockItem, this);
- if (SanityManager.DEBUG)
+ if (SanityManager.DEBUG)
{
if (SanityManager.DEBUG_ON("DeadlockTrace"))
{
@@ -391,11 +403,17 @@ final class ConcurrentLockSet implements
}
}
- return null;
+ return null;
}
} finally {
entry.unlock();
+
+ if ( blockedByParent )
+ {
+ throw StandardException.newException
+ ( SQLState.SELF_DEADLOCK );
+ }
}
boolean deadlockWait = false;
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/LockControl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/LockControl.java?rev=1593702&r1=1593701&r2=1593702&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/LockControl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/LockControl.java Sat May 10 13:55:50 2014
@@ -24,6 +24,7 @@ package org.apache.derby.impl.services.l
import org.apache.derby.iapi.services.locks.CompatibilitySpace;
import org.apache.derby.iapi.services.locks.Lockable;
import org.apache.derby.iapi.services.locks.Latch;
+import org.apache.derby.iapi.services.locks.LockOwner;
import org.apache.derby.shared.common.sanity.SanityManager;
@@ -599,6 +600,42 @@ final class LockControl implements Contr
return null;
}
+ /**
+ * <p>
+ * Returns true if the childLock is blocked because its parent owns
+ * a conficting lock.
+ * This code was written to support the fix to DERBY-6554. The only known
+ * way that this condition arises is when a write attempt by a nested user
+ * transaction is blocked by a read lock held by the main transaction.
+ * This only happens while trying to write to SYS.SYSSEQUENCES while
+ * managing sequence generators.
+ * </p>
+ */
+ public boolean blockedByParent( Lock childLock )
+ {
+ if ( granted == null ) { return false; }
+
+ LockOwner childOwner = childLock.getCompatabilitySpace().getOwner();
+ Object requestedQualifier = childLock.getQualifier();
+
+ for ( Lock grantedLock : granted )
+ {
+ LockOwner ownerOfGrant = grantedLock.getCompatabilitySpace().getOwner();
+
+ if ( childOwner.nestsUnder( ownerOfGrant ) )
+ {
+ Object grantedQualifier = grantedLock.getQualifier();
+
+ if ( !grantedLock.getLockable().requestCompatible( requestedQualifier, grantedQualifier ) )
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
//EXCLUDE-START-lockdiag-
/**
* make a shallow clone of myself
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/UpdateLoader.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/UpdateLoader.java?rev=1593702&r1=1593701&r2=1593702&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/UpdateLoader.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/UpdateLoader.java Sat May 10 13:55:50 2014
@@ -414,6 +414,17 @@ final class UpdateLoader implements Lock
public boolean noWait() {
return false;
}
+
+ public boolean isNestedOwner()
+ {
+ return false;
+ }
+
+ public boolean nestsUnder( LockOwner other )
+ {
+ return false;
+ }
+
}
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SequenceUpdater.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SequenceUpdater.java?rev=1593702&r1=1593701&r2=1593702&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SequenceUpdater.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SequenceUpdater.java Sat May 10 13:55:50 2014
@@ -449,6 +449,7 @@ public abstract class SequenceUpdater im
if ( nestedTransaction != null )
{
boolean retval = false;
+ boolean escalateToParentTransaction = false;
try
{
@@ -456,7 +457,20 @@ public abstract class SequenceUpdater im
}
catch (StandardException se)
{
- if ( !se.isLockTimeout() ) { throw se; }
+ if ( !se.isLockTimeout() )
+ {
+ if ( se.isSelfDeadlock() )
+ {
+ // We're blocked by a lock held by our parent transaction.
+ // Escalate into the parent transaction now. See DERBY-6554.
+ escalateToParentTransaction = true;
+ }
+ else
+ {
+ Monitor.logThrowable( se );
+ throw se;
+ }
+ }
}
finally
{
@@ -467,6 +481,11 @@ public abstract class SequenceUpdater im
nestedTransaction.commit();
nestedTransaction.destroy();
+ if ( escalateToParentTransaction )
+ {
+ retval = updateCurrentValueOnDisk( executionTransaction, oldValue, newValue, false );
+ }
+
return retval;
}
}
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertResultSet.java?rev=1593702&r1=1593701&r2=1593702&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertResultSet.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertResultSet.java Sat May 10 13:55:50 2014
@@ -820,7 +820,10 @@ class InsertResultSet extends DMLWriteRe
throw se;
}
- if (se.getMessageId().equals(SQLState.LOCK_TIMEOUT))
+ if (
+ se.getMessageId().equals(SQLState.LOCK_TIMEOUT) ||
+ se.getMessageId().equals(SQLState.SELF_DEADLOCK)
+ )
{
// if we couldn't do this with a nested xaction, retry with
// parent-- we need to wait this time!
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/RAMTransaction.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/RAMTransaction.java?rev=1593702&r1=1593701&r2=1593702&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/RAMTransaction.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/RAMTransaction.java Sat May 10 13:55:50 2014
@@ -1431,9 +1431,8 @@ public class RAMTransaction
long conglomId)
throws StandardException
{
- findExistingConglomerate(conglomId).purgeConglomerate(
- this,
- rawtran);
+ findExistingConglomerate(conglomId).purgeConglomerate
+ ( this, rawtran );
return;
}
@@ -2320,10 +2319,12 @@ public class RAMTransaction
Transaction child_rawtran =
((readOnly) ?
accessmanager.getRawStore().startNestedReadOnlyUserTransaction(
+ rawtran,
getLockSpace(),
cm,
AccessFactoryGlobals.NESTED_READONLY_USER_TRANS) :
accessmanager.getRawStore().startNestedUpdateUserTransaction(
+ rawtran,
cm,
AccessFactoryGlobals.NESTED_UPDATE_USER_TRANS,
flush_log_on_xact_end));
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/heap/HeapController.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/heap/HeapController.java?rev=1593702&r1=1593701&r2=1593702&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/heap/HeapController.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/heap/HeapController.java Sat May 10 13:55:50 2014
@@ -549,10 +549,17 @@ public class HeapController
protected boolean lockRowAtSlotNoWaitExclusive(RecordHandle rh)
throws StandardException
{
- return(
- open_conglom.getContainer().getLockingPolicy().
- lockRecordForWrite(
- open_conglom.getRawTran(), rh, false, false));
+ try {
+ return(
+ open_conglom.getContainer().getLockingPolicy().
+ lockRecordForWrite
+ ( open_conglom.getRawTran(), rh, false, false) );
+ }
+ catch (StandardException se)
+ {
+ if ( se.isSelfDeadlock() ) { return false; }
+ else { throw se; }
+ }
}
protected void removePage(Page page)
throws StandardException
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/RawStore.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/RawStore.java?rev=1593702&r1=1593701&r2=1593702&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/RawStore.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/RawStore.java Sat May 10 13:55:50 2014
@@ -435,25 +435,31 @@ public final class RawStore implements R
}
public Transaction startNestedReadOnlyUserTransaction(
+ Transaction parentTransaction,
CompatibilitySpace compatibilitySpace,
ContextManager contextMgr,
String transName)
throws StandardException
{
return(
- xactFactory.startNestedReadOnlyUserTransaction(
- this, compatibilitySpace, contextMgr, transName));
+ xactFactory.startNestedReadOnlyUserTransaction
+ (
+ this, (RawTransaction) parentTransaction, compatibilitySpace, contextMgr, transName)
+ );
}
public Transaction startNestedUpdateUserTransaction(
+ Transaction parentTransaction,
ContextManager contextMgr,
String transName,
boolean flush_log_on_xact_end)
throws StandardException
{
return(
- xactFactory.startNestedUpdateUserTransaction(
- this, contextMgr, transName, flush_log_on_xact_end));
+ xactFactory.startNestedUpdateUserTransaction
+ (
+ this, (RawTransaction) parentTransaction, contextMgr, transName, flush_log_on_xact_end)
+ );
}
public Transaction findUserTransaction(
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/InternalXact.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/InternalXact.java?rev=1593702&r1=1593701&r2=1593702&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/InternalXact.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/InternalXact.java Sat May 10 13:55:50 2014
@@ -56,7 +56,7 @@ public class InternalXact extends Xact
DataValueFactory dataValueFactory)
{
super(
- xactFactory, logFactory, dataFactory, dataValueFactory,
+ xactFactory, null, logFactory, dataFactory, dataValueFactory,
false, null, false);
// always want to hold latches & containers open past the commit/abort
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/Xact.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/Xact.java?rev=1593702&r1=1593701&r2=1593702&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/Xact.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/Xact.java Sat May 10 13:55:50 2014
@@ -179,6 +179,9 @@ public class Xact extends RawTransaction
// id that is valid locally in this raw store.
private volatile TransactionId myId;
+ // id of parent transaction if this is a nested user transaction
+ private volatile TransactionId parentTransactionId;
+
protected Logger logger; // the object we use to access the log.
@@ -272,8 +275,9 @@ public class Xact extends RawTransaction
** Constructor
*/
- protected Xact(
+ protected Xact(
XactFactory xactFactory,
+ Xact parentTransaction,
LogFactory logFactory,
DataFactory dataFactory,
DataValueFactory dataValueFactory,
@@ -285,6 +289,10 @@ public class Xact extends RawTransaction
super();
this.xactFactory = xactFactory;
+ if ( parentTransaction != null )
+ {
+ parentTransactionId = parentTransaction.getId();
+ }
this.logFactory = logFactory;
this.dataFactory = dataFactory;
this.dataValueFactory = dataValueFactory;
@@ -2834,6 +2842,19 @@ public class Xact extends RawTransaction
logFactory.checkpointInRFR(cinstant, redoLWM, undoLWM, dataFactory);
}
+ public boolean isNestedOwner()
+ {
+ return (parentTransactionId != null );
+ }
+
+ public boolean nestsUnder( LockOwner other )
+ {
+ if ( parentTransactionId == null ) { return false; }
+ else if ( !(other instanceof Xact) ) { return false; }
+ {
+ return parentTransactionId.equals( ((Xact) other).getId() );
+ }
+ }
}
class LockCount {
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/XactFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/XactFactory.java?rev=1593702&r1=1593701&r2=1593702&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/XactFactory.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/XactFactory.java Sat May 10 13:55:50 2014
@@ -253,6 +253,7 @@ public class XactFactory implements Tran
* Common work done to create local or global transactions.
*
* @param rsf the raw store factory creating this xact.
+ * @param parentTransaction parent transaction (if this is a nested user transaction)
* @param cm the current context manager to associate the xact with.
* @param compatibilitySpace
* if null, use the transaction being created, else if
@@ -262,6 +263,7 @@ public class XactFactory implements Tran
**/
private Xact startCommonTransaction(
RawStoreFactory rsf,
+ Xact parentTransaction,
ContextManager cm,
boolean readOnly,
CompatibilitySpace compatibilitySpace,
@@ -284,7 +286,7 @@ public class XactFactory implements Tran
Xact xact =
new Xact(
- this, logFactory, dataFactory, dataValueFactory,
+ this, parentTransaction, logFactory, dataFactory, dataValueFactory,
readOnly, compatibilitySpace, flush_log_on_xact_end);
xact.setTransName(transName);
@@ -304,6 +306,7 @@ public class XactFactory implements Tran
return(
startCommonTransaction(
rsf,
+ null,
cm,
false, // user xact always read/write
null,
@@ -315,6 +318,7 @@ public class XactFactory implements Tran
public RawTransaction startNestedReadOnlyUserTransaction(
RawStoreFactory rsf,
+ RawTransaction parentTransaction,
CompatibilitySpace compatibilitySpace,
ContextManager cm,
String transName)
@@ -323,6 +327,7 @@ public class XactFactory implements Tran
return(
startCommonTransaction(
rsf,
+ (Xact) parentTransaction,
cm,
true,
compatibilitySpace,
@@ -335,6 +340,7 @@ public class XactFactory implements Tran
public RawTransaction startNestedUpdateUserTransaction(
RawStoreFactory rsf,
+ RawTransaction parentTransaction,
ContextManager cm,
String transName,
boolean flush_log_on_xact_end)
@@ -343,6 +349,7 @@ public class XactFactory implements Tran
return(
startCommonTransaction(
rsf,
+ (Xact) parentTransaction,
cm,
false,
null,
@@ -373,6 +380,7 @@ public class XactFactory implements Tran
Xact xact =
startCommonTransaction(
rsf,
+ null,
cm,
false,
null,
@@ -426,7 +434,7 @@ public class XactFactory implements Tran
Xact xact =
new Xact(
- this, logFactory, dataFactory, dataValueFactory,
+ this, null, logFactory, dataFactory, dataValueFactory,
false, null, false);
// hold latches etc. past commit in NTT
Modified: db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml?rev=1593702&r1=1593701&r2=1593702&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml Sat May 10 13:55:50 2014
@@ -1127,6 +1127,11 @@ Guide.
</msg>
<msg>
+ <name>40XL2</name>
+ <text>Self-deadlock.</text>
+ </msg>
+
+ <msg>
<name>40XT0</name>
<text>An internal error was identified by RawStore module.</text>
</msg>
Modified: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java?rev=1593702&r1=1593701&r2=1593702&view=diff
==============================================================================
--- db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java (original)
+++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java Sat May 10 13:55:50 2014
@@ -271,6 +271,7 @@ public interface SQLState {
String DEADLOCK = "40001";
String LOCK_TIMEOUT = "40XL1";
String LOCK_TIMEOUT_LOG = "40XL1.T.1";
+ String SELF_DEADLOCK = "40XL2";
/*
** Store - access.protocol.Interface statement exceptions
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SequenceTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SequenceTest.java?rev=1593702&r1=1593701&r2=1593702&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SequenceTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SequenceTest.java Sat May 10 13:55:50 2014
@@ -644,6 +644,67 @@ public class SequenceTest extends Genera
}
/**
+ * Verify that a sequence can be used in the same transaction
+ * which created it.
+ */
+ public void test_17_6554() throws Exception
+ {
+ Connection alphaConn = openUserConnection( ALPHA );
+ Connection betaConn = openUserConnection( BETA );
+
+ alphaConn.setAutoCommit( false );
+ betaConn.setAutoCommit( false );
+
+ String createSequence = "create sequence seq6554";
+ String nextValueFor = "values next value for seq6554";
+ String[][] nextValueForResults =
+ new String[][]
+ {
+ { "-2147483648" },
+ };
+
+ goodStatement( alphaConn, createSequence );
+ assertResults( alphaConn, nextValueFor, nextValueForResults, true );
+ alphaConn.rollback();
+
+ goodStatement( betaConn, createSequence );
+ assertResults( betaConn, nextValueFor, nextValueForResults, true );
+ betaConn.rollback();
+
+ // now try creating and using the sequence inside the nested
+ // transaction context of a database procedure
+
+ goodStatement
+ (
+ alphaConn,
+ "create procedure createSequence( sequenceName varchar( 128 ) )\n" +
+ "language java parameter style java modifies sql data\n" +
+ "external name 'org.apache.derbyTesting.functionTests.tests.lang.SequenceTest.createSequence'\n"
+ );
+ goodStatement( alphaConn, "grant execute on procedure createSequence to public" );
+ alphaConn.commit();
+
+ String runProcedure = "call alpha.createSequence( 'seq6554_2' )";
+ String postProcedureQuery= "values next value for seq6554_2";
+ String[][] postProcedureResults =
+ new String[][]
+ {
+ { "-2147483647" },
+ };
+
+ goodStatement( alphaConn, runProcedure );
+ assertResults( alphaConn, postProcedureQuery, postProcedureResults, true );
+ alphaConn.rollback();
+
+ goodStatement( betaConn, runProcedure );
+ assertResults( betaConn, postProcedureQuery, postProcedureResults, true );
+ betaConn.rollback();
+
+ alphaConn.setAutoCommit( true );
+ betaConn.setAutoCommit( true );
+ }
+
+ /**
* Verify that sequence numbers pick up where they left off after eviction from
* the sequence cache.
*/