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 ka...@apache.org on 2007/03/12 09:40:07 UTC
svn commit: r517131 - in
/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda:
DRDAConnThread.java DRDAXAProtocol.java
Author: kahatlen
Date: Mon Mar 12 01:40:06 2007
New Revision: 517131
URL: http://svn.apache.org/viewvc?view=rev&rev=517131
Log:
DERBY-2220: Uncommitted transactions executed through XAResource will
hold locks after the application terminates (or crashes during the
transaction).
Abort the global transaction on a derby server when the network socket
is closed.
Patch contributed by Julius Stroffek.
Modified:
db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java
db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAXAProtocol.java
Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java?view=diff&rev=517131&r1=517130&r2=517131
==============================================================================
--- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java (original)
+++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java Mon Mar 12 01:40:06 2007
@@ -7556,6 +7556,12 @@
{
if (session == null)
return;
+
+ /* DERBY-2220: Rollback the current XA transaction if it is
+ still associated with the connection. */
+ if (xaProto != null)
+ xaProto.rollbackCurrentTransaction();
+
server.removeFromSessionTable(session.connNum);
try {
session.close();
Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAXAProtocol.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAXAProtocol.java?view=diff&rev=517131&r1=517130&r2=517131
==============================================================================
--- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAXAProtocol.java (original)
+++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAXAProtocol.java Mon Mar 12 01:40:06 2007
@@ -37,6 +37,9 @@
private DRDAConnThread connThread;
private DDMReader reader;
private DDMWriter writer;
+ /** Holds the Xid of the global transaction associated with
+ * the corresponding DRDAConnThread (and connection itself). */
+ private Xid xid;
DRDAXAProtocol(DRDAConnThread connThread)
@@ -44,7 +47,7 @@
this.connThread = connThread;
reader = connThread.getReader();
writer = connThread.getWriter();
-
+ xid = null;
}
@@ -142,7 +145,7 @@
break;
case CodePoint.SYNCTYPE_ROLLBACK:
//rollback sync type
- rollbackTransaction(xid);
+ rollbackTransaction(xid, true);
break;
case CodePoint.SYNCTYPE_INDOUBT:
//recover sync type
@@ -239,6 +242,7 @@
try {
if (xid.getFormatId() != -1)
xaResource.start(xid,xaflags);
+ this.xid = xid;
} catch (XAException xe)
{
xaRetVal = processXAException(xe);
@@ -319,24 +323,29 @@
}
/**
- * Rollback transaction
+ * Rollback transaction. Optionally send SYNCCRD response.
* @param xid Xid for rollback for global transaction.
* If xid formatid is -1 it represents a local transaction
+ * @param sendSYNCCRD Indicates whether the function should
+ * send a SYNCCRD response
*/
- private void rollbackTransaction(Xid xid) throws DRDAProtocolException
+ private void rollbackTransaction(Xid xid, boolean sendSYNCCRD) throws DRDAProtocolException
{
boolean local = ( xid.getFormatId() == -1);
if (local)
- rollbackLocalTransaction();
+ rollbackLocalTransaction(sendSYNCCRD);
else
- rollbackXATransaction(xid);
+ rollbackXATransaction(xid, sendSYNCCRD);
}
/**
- * Rollback a local transaction
+ * Rollback a local transaction. Optionally send SYNCCRD response.
*
+ * @param sendSYNCCRD Indicates whether the function should
+ * send a SYNCCRD response
+ * @throws DRDAProtocolException
*/
- private void rollbackLocalTransaction() throws DRDAProtocolException
+ private void rollbackLocalTransaction(boolean sendSYNCCRD) throws DRDAProtocolException
{
int xaRetVal = XAResource.XA_OK;
try {
@@ -351,18 +360,21 @@
}
}
- writeSYNCCRD(CodePoint.SYNCTYPE_COMMITTED,
- xaRetVal, null);
-
+ if (sendSYNCCRD) {
+ writeSYNCCRD(CodePoint.SYNCTYPE_COMMITTED,
+ xaRetVal, null);
+ }
}
/**
- * Rollback the xa transaction. Send SYNCCRD response.
+ * Rollback the xa transaction. Optionally send SYNCCRD response.
*
* @param xid - XID
+ * @param sendSYNCCRD Indicates whether the function should
+ * send a SYNCCRD response
* @throws DRDAProtocolException
*/
- private void rollbackXATransaction(Xid xid) throws DRDAProtocolException
+ private void rollbackXATransaction(Xid xid, boolean sendSYNCCRD) throws DRDAProtocolException
{
XAResource xaResource = getXAResource();
int xaRetVal = xaResource.XA_OK;
@@ -377,9 +389,10 @@
{
xaRetVal = processXAException(xe);
}
- writeSYNCCRD(CodePoint.SYNCTYPE_ROLLBACK,
- xaRetVal, null);
-
+ if (sendSYNCCRD) {
+ writeSYNCCRD(CodePoint.SYNCTYPE_ROLLBACK,
+ xaRetVal, null);
+ }
}
/**
@@ -396,6 +409,7 @@
try {
xaResource.end(xid,xaflags);
+ xid = null;
if (SanityManager.DEBUG)
{
connThread.trace("ended XA transaction. xid = " + xid +
@@ -658,15 +672,44 @@
return xaRetVal;
}
-}
-
-
-
-
-
-
-
-
-
+ /**
+ * This function rollbacks the current global transaction associated
+ * with the XAResource or a local transaction. The function should
+ * be called only in exceptional cases - like client socket
+ * is closed. */
+ void rollbackCurrentTransaction()
+ {
+ if (xid != null) {
+ boolean local = ( xid.getFormatId() == -1);
+ try {
+ // if the transaction is not local disassociate the transaction from
+ // the connection first because the rollback can not be performed
+ // on a transaction associated with the XAResource
+ try {
+ if (!local) {
+ XAResource xaResource = getXAResource();
+ // this will throw the XAException (because TMFAIL
+ // will throw an exception)
+ xaResource.end(xid, XAResource.TMFAIL);
+ }
+ } catch (XAException e) {
+ // do not print out the exception generally thrown
+ // when TMFAIL flag is present
+ if (e.errorCode < XAException.XA_RBBASE
+ || e.errorCode > XAException.XA_RBEND) {
+ connThread.getServer().consoleExceptionPrint(e);
+ }
+ }
+ rollbackTransaction(xid, false);
+ } catch (DRDAProtocolException e) {
+ // because we do not dump any DRDA stuff to the socket
+ // the exception can not be thrown in this case
+ // However, we will dump the exception to the console
+ connThread.getServer().consoleExceptionPrint(e);
+ }
+ xid = null;
+ }
+ }
+}