You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2012/08/03 12:17:40 UTC
svn commit: r1368866 - in /jackrabbit/branches/2.4: ./
jackrabbit-core/src/main/java/org/apache/jackrabbit/core/util/db/ConnectionHelper.java
Author: jukka
Date: Fri Aug 3 10:17:39 2012
New Revision: 1368866
URL: http://svn.apache.org/viewvc?rev=1368866&view=rev
Log:
2.4: Merged revision 1352791 (JCR-3349)
Modified:
jackrabbit/branches/2.4/ (props changed)
jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/util/db/ConnectionHelper.java
Propchange: jackrabbit/branches/2.4/
------------------------------------------------------------------------------
Merged /jackrabbit/trunk:r1352791
Modified: jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/util/db/ConnectionHelper.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/util/db/ConnectionHelper.java?rev=1368866&r1=1368865&r2=1368866&view=diff
==============================================================================
--- jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/util/db/ConnectionHelper.java (original)
+++ jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/util/db/ConnectionHelper.java Fri Aug 3 10:17:39 2012
@@ -22,9 +22,14 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
import javax.sql.DataSource;
+import javax.transaction.xa.Xid;
+import org.apache.jackrabbit.core.TransactionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -77,7 +82,8 @@ public class ConnectionHelper {
protected final DataSource dataSource;
private ThreadLocal<Connection> batchConnectionTl = new ThreadLocal<Connection>();
-
+ private Map<String, Connection> xaBatchConnectionMap = Collections.synchronizedMap(new HashMap<String, Connection>());
+
/**
* The default fetchSize is '0'. This means the fetchSize Hint will be ignored
*/
@@ -166,12 +172,11 @@ public class ConnectionHelper {
* Returns true if we are currently in a batch mode, false otherwise.
* @return true if the current thread is running in batch mode, false otherwise.
*/
- protected boolean inBatchMode()
- {
- return batchConnectionTl.get() != null;
+ protected boolean inBatchMode() {
+ return getTransactionAwareBatchConnection() != null;
}
- /**
+ /**
* The default implementation returns the {@code extraNameCharacters} provided by the databases metadata.
*
* @return the additional characters for identifiers supported by the db
@@ -233,18 +238,18 @@ public class ConnectionHelper {
try {
batchConnection = getConnection();
batchConnection.setAutoCommit(false);
- batchConnectionTl.set(batchConnection);
+ setTransactionAwareBatchConnection(batchConnection);
} catch (SQLException e) {
// Strive for failure atomicity
if (batchConnection != null) {
DbUtility.close(batchConnection, null, null);
}
- batchConnectionTl.remove();
+ removeTransactionAwareBatchConnection();
throw e;
}
}
- /**
+ /**
* This method always ends the <i>batch mode</i>.
*
* @param commit whether the changes in the batch should be committed or rolled back
@@ -257,13 +262,13 @@ public class ConnectionHelper {
}
try {
if (commit) {
- batchConnectionTl.get().commit();
+ getTransactionAwareBatchConnection().commit();
} else {
- batchConnectionTl.get().rollback();
+ getTransactionAwareBatchConnection().rollback();
}
} finally {
- DbUtility.close(batchConnectionTl.get(), null, null);
- batchConnectionTl.set(null);
+ DbUtility.close(getTransactionAwareBatchConnection(), null, null);
+ removeTransactionAwareBatchConnection();
}
}
@@ -423,7 +428,7 @@ public class ConnectionHelper {
*/
protected final Connection getConnection() throws SQLException {
if (inBatchMode()) {
- return batchConnectionTl.get();
+ return getTransactionAwareBatchConnection();
} else {
Connection con = dataSource.getConnection();
// JCR-1013: Setter may fail unnecessarily on a managed connection
@@ -435,6 +440,70 @@ public class ConnectionHelper {
}
/**
+ * Returns the Batch Connection. In XA Environment it is stored
+ * in a Cache-Map based on the current Xid. In Non-XA Environment a ThreadLocal is used.
+ *
+ * @return Connection
+ */
+ private Connection getTransactionAwareBatchConnection() {
+ Xid currentXid = TransactionContext.getCurrentXid();
+ if (currentXid != null) {
+ return xaBatchConnectionMap.get(xidtoString(currentXid.getGlobalTransactionId()));
+ } else {
+ return batchConnectionTl.get();
+ }
+ }
+
+ /**
+ * Setter for the Batch Connection. In XA Environment it will be stored
+ * in a Cache-Map based on the current Xid. In Non-XA Environment a ThreadLocal is used.
+ *
+ * @param batchConnection
+ */
+ private void setTransactionAwareBatchConnection(Connection batchConnection) {
+ Xid currentXid = TransactionContext.getCurrentXid();
+ if (currentXid != null) {
+ xaBatchConnectionMap.put(xidtoString(currentXid.getGlobalTransactionId()), batchConnection);
+ } else {
+ batchConnectionTl.set(batchConnection);
+ }
+ }
+
+ /**
+ * Removes the Batch Connection. In XA Environment it will be stored
+ * in a Cache-Map based on the current Xid. In Non-XA Environment a ThreadLocal is used.
+ */
+ private void removeTransactionAwareBatchConnection() {
+ Xid currentXid = TransactionContext.getCurrentXid();
+ if (currentXid != null) {
+ xaBatchConnectionMap.remove(xidtoString(currentXid.getGlobalTransactionId()));
+ } else {
+ batchConnectionTl.remove();
+ }
+ }
+
+ /**
+ * Creates a comparable String from the given GlobalTransactionId byte[]
+ *
+ * @param gtrid
+ * @return String
+ */
+ private String xidtoString(byte[] gtrid) {
+ int hexVal;
+ StringBuffer sb = new StringBuffer(512);
+ sb.append(" gtrid(" + gtrid.length + ")={0x");
+ for (int i=0; i<gtrid.length; i++) {
+ hexVal = gtrid[i]&0xFF;
+ if ( hexVal < 0x10 )
+ sb.append("0" + Integer.toHexString(gtrid[i]&0xFF));
+ else
+ sb.append(Integer.toHexString(gtrid[i]&0xFF));
+ }
+ sb.append("}");
+ return sb.toString();
+ }
+
+ /**
* Closes the given resources given the {@code batchMode} state.
*
* @param con the {@code Connection} obtained through the {@link #getConnection()} method