From 23aac3367546ab197cd823055fb7ebaed1022c08 Mon Sep 17 00:00:00 2001 From: Afsaneh Rafighi Date: Mon, 11 Dec 2017 17:39:09 -0800 Subject: [PATCH 1/3] make recovery work after ms dtc restart --- .../sqlserver/jdbc/SQLServerXAResource.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerXAResource.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerXAResource.java index 8e72d0f35..89c898f4b 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerXAResource.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerXAResource.java @@ -165,7 +165,10 @@ public final class SQLServerXAResource implements javax.transaction.xa.XAResourc public static final int SSTRANSTIGHTLYCPLD = 0x8000; private SQLServerCallableStatement[] xaStatements = {null, null, null, null, null, null, null, null, null, null}; private final String traceID; - + /** + * Variable that shows how many times we attempt the recovery, e.g in case of ms DTC restart + */ + private int recoveryAttempt = 0; static { xaInitLock = new Object(); } @@ -634,6 +637,14 @@ else if (-1 != version.indexOf('.')) { } } } + if (XA_RECOVER == nType && XA_OK != nStatus && recoveryAttempt < 1) { + // if recover failed, attempt to start again - adding the variable to check to attempt only once otherwise throw exception that recovery fails + // this is added since before this change, if we restart the ms dtc and attempt to do recovery, driver will throw exception + //"The function RECOVER: failed. The status is: -3" + recoveryAttempt ++; + DTC_XA_Interface(XA_START, xid, xaFlags); + return DTC_XA_Interface(XA_RECOVER, xid, xaFlags); + } // prepare and end can return XA_RDONLY // Think should we just check for nStatus to be greater than or equal to zero instead of this check if (((XA_RDONLY == nStatus) && (XA_END != nType && XA_PREPARE != nType)) || (XA_OK != nStatus && XA_RDONLY != nStatus)) { @@ -658,7 +669,6 @@ else if (-1 != version.indexOf('.')) { xaLogger.finer(toString() + " Ignoring exception:" + e1); } } - throw e; } else { From 755b9c6062b05f93c2a602367f1c453f7bc0410b Mon Sep 17 00:00:00 2001 From: Afsaneh Rafighi Date: Tue, 12 Dec 2017 17:32:06 -0800 Subject: [PATCH 2/3] upadate comments and remove an unused import --- .../com/microsoft/sqlserver/jdbc/SQLServerXAResource.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerXAResource.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerXAResource.java index 89c898f4b..63b02d49a 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerXAResource.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerXAResource.java @@ -16,11 +16,9 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.Properties; -import java.util.Vector; import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Level; import java.util.logging.Logger; - import javax.transaction.xa.XAException; import javax.transaction.xa.XAResource; import javax.transaction.xa.Xid; @@ -166,7 +164,7 @@ public final class SQLServerXAResource implements javax.transaction.xa.XAResourc private SQLServerCallableStatement[] xaStatements = {null, null, null, null, null, null, null, null, null, null}; private final String traceID; /** - * Variable that shows how many times we attempt the recovery, e.g in case of ms DTC restart + * Variable that shows how many times we attempt the recovery, e.g in case of MSDTC restart */ private int recoveryAttempt = 0; static { @@ -639,9 +637,9 @@ else if (-1 != version.indexOf('.')) { } if (XA_RECOVER == nType && XA_OK != nStatus && recoveryAttempt < 1) { // if recover failed, attempt to start again - adding the variable to check to attempt only once otherwise throw exception that recovery fails - // this is added since before this change, if we restart the ms dtc and attempt to do recovery, driver will throw exception + // this is added since before this change, if we restart the MSDTC and attempt to do recovery, driver will throw exception //"The function RECOVER: failed. The status is: -3" - recoveryAttempt ++; + recoveryAttempt++; DTC_XA_Interface(XA_START, xid, xaFlags); return DTC_XA_Interface(XA_RECOVER, xid, xaFlags); } From 877cd7a1c847464d16d353745f17bd1b53d7c14f Mon Sep 17 00:00:00 2001 From: Afsaneh Rafighi Date: Wed, 3 Jan 2018 17:48:07 -0800 Subject: [PATCH 3/3] update the dtc_xa_interface to use the correct flag for xa_start --- .../com/microsoft/sqlserver/jdbc/SQLServerXAResource.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerXAResource.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerXAResource.java index 63b02d49a..53ff357d4 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerXAResource.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerXAResource.java @@ -382,7 +382,7 @@ private String typeDisplay(int type) { SQLServerCallableStatement cs = null; try { synchronized (this) { - if (!xaInitDone) { + if (!xaInitDone) { try { synchronized (xaInitLock) { SQLServerCallableStatement initCS = null; @@ -640,7 +640,7 @@ else if (-1 != version.indexOf('.')) { // this is added since before this change, if we restart the MSDTC and attempt to do recovery, driver will throw exception //"The function RECOVER: failed. The status is: -3" recoveryAttempt++; - DTC_XA_Interface(XA_START, xid, xaFlags); + DTC_XA_Interface(XA_START, xid, TMNOFLAGS); return DTC_XA_Interface(XA_RECOVER, xid, xaFlags); } // prepare and end can return XA_RDONLY