Skip to content

Commit

Permalink
[CONJ-1189] support for pinGlobalTxToPhysicalConnection option
Browse files Browse the repository at this point in the history
  • Loading branch information
rusher committed Jul 8, 2024
1 parent 873dde7 commit 45d8e6d
Show file tree
Hide file tree
Showing 7 changed files with 300 additions and 65 deletions.
29 changes: 29 additions & 0 deletions src/main/java/org/mariadb/jdbc/Configuration.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ public class Configuration {
private String geometryDefaultType = null;
private String restrictedAuth = null;
private String initSql = null;
private boolean pinGlobalTxToPhysicalConnection = false;

// socket
private String socketFactory = null;
Expand Down Expand Up @@ -184,6 +185,7 @@ private Configuration(
boolean returnMultiValuesGeneratedIds,
boolean jdbcCompliantTruncation,
boolean permitRedirect,
boolean pinGlobalTxToPhysicalConnection,
TransactionIsolation transactionIsolation,
int defaultFetchSize,
int maxQuerySizeToLog,
Expand Down Expand Up @@ -269,6 +271,7 @@ private Configuration(
this.returnMultiValuesGeneratedIds = returnMultiValuesGeneratedIds;
this.jdbcCompliantTruncation = jdbcCompliantTruncation;
this.permitRedirect = permitRedirect;
this.pinGlobalTxToPhysicalConnection = pinGlobalTxToPhysicalConnection;
this.useLocalSessionState = useLocalSessionState;
this.transactionIsolation = transactionIsolation;
this.defaultFetchSize = defaultFetchSize;
Expand Down Expand Up @@ -394,6 +397,7 @@ private Configuration(
Boolean returnMultiValuesGeneratedIds,
Boolean jdbcCompliantTruncation,
Boolean permitRedirect,
Boolean pinGlobalTxToPhysicalConnection,
Boolean includeInnodbStatusInDeadlockExceptions,
Boolean includeThreadDumpInDeadlockExceptions,
String servicePrincipalName,
Expand Down Expand Up @@ -511,6 +515,8 @@ private Configuration(
this.returnMultiValuesGeneratedIds = returnMultiValuesGeneratedIds;
if (jdbcCompliantTruncation != null) this.jdbcCompliantTruncation = jdbcCompliantTruncation;
if (permitRedirect != null) this.permitRedirect = permitRedirect;
if (pinGlobalTxToPhysicalConnection != null)
this.pinGlobalTxToPhysicalConnection = pinGlobalTxToPhysicalConnection;
if (includeInnodbStatusInDeadlockExceptions != null)
this.includeInnodbStatusInDeadlockExceptions = includeInnodbStatusInDeadlockExceptions;
if (includeThreadDumpInDeadlockExceptions != null)
Expand Down Expand Up @@ -656,6 +662,7 @@ public Builder toBuilder() {
.returnMultiValuesGeneratedIds(this.returnMultiValuesGeneratedIds)
.jdbcCompliantTruncation(this.jdbcCompliantTruncation)
.permitRedirect(this.permitRedirect)
.pinGlobalTxToPhysicalConnection(this.pinGlobalTxToPhysicalConnection)
.transactionIsolation(
transactionIsolation == null ? null : this.transactionIsolation.getValue())
.defaultFetchSize(this.defaultFetchSize)
Expand Down Expand Up @@ -1803,6 +1810,15 @@ public boolean permitRedirect() {
return permitRedirect;
}

/**
* When enabled, ensure that for XA operation to use the same connection
*
* @return pinGlobalTxToPhysicalConnection
*/
public boolean pinGlobalTxToPhysicalConnection() {
return pinGlobalTxToPhysicalConnection;
}

/**
* On deadlock exception, must driver execute additional commands to show innodb status in error
* description.
Expand Down Expand Up @@ -2119,6 +2135,7 @@ public static final class Builder implements Cloneable {
private Boolean returnMultiValuesGeneratedIds;
private Boolean jdbcCompliantTruncation;
private Boolean permitRedirect;
private Boolean pinGlobalTxToPhysicalConnection;
private Integer defaultFetchSize;
private Integer maxQuerySizeToLog;
private Integer maxAllowedPacket;
Expand Down Expand Up @@ -3011,6 +3028,17 @@ public Builder permitRedirect(Boolean permitRedirect) {
return this;
}

/**
* Indicate if for XA transaction, connector must reuse same connection.
*
* @param pinGlobalTxToPhysicalConnection force reuse of same connection
* @return this {@link Builder}
*/
public Builder pinGlobalTxToPhysicalConnection(Boolean pinGlobalTxToPhysicalConnection) {
this.pinGlobalTxToPhysicalConnection = pinGlobalTxToPhysicalConnection;
return this;
}

/**
* On dead-lock exception must add innodb status in exception error message. If enabled, an
* additional command will be done to retrieve innodb status when dead-lock occurs.
Expand Down Expand Up @@ -3336,6 +3364,7 @@ public Configuration build() throws SQLException {
this.returnMultiValuesGeneratedIds,
this.jdbcCompliantTruncation,
this.permitRedirect,
this.pinGlobalTxToPhysicalConnection,
this.includeInnodbStatusInDeadlockExceptions,
this.includeThreadDumpInDeadlockExceptions,
this.servicePrincipalName,
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/org/mariadb/jdbc/Connection.java
Original file line number Diff line number Diff line change
Expand Up @@ -906,6 +906,15 @@ public QueryTimeoutHandler handleTimeout(int queryTimeout) {
return queryTimeoutHandler.create(queryTimeout);
}

/**
* Internal : retrieve internal ClosableLock
*
* @return ClosableLock
*/
protected ClosableLock getLock() {
return lock;
}

/**
* for _TEST_ only
*
Expand Down
20 changes: 16 additions & 4 deletions src/main/java/org/mariadb/jdbc/MariaDbDataSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -207,28 +207,40 @@ public Logger getParentLogger() {
@Override
public PooledConnection getPooledConnection() throws SQLException {
if (conf == null) config();
return new MariaDbPoolConnection(Driver.connect(conf));
org.mariadb.jdbc.Connection conn = Driver.connect(conf);
return conf.pinGlobalTxToPhysicalConnection()
? new MariaDbPoolPinnedConnection(conn)
: new MariaDbPoolConnection(conn);
}

@Override
public PooledConnection getPooledConnection(String username, String password)
throws SQLException {
if (conf == null) config();
Configuration conf = this.conf.clone(username, password);
return new MariaDbPoolConnection(Driver.connect(conf));
org.mariadb.jdbc.Connection conn = Driver.connect(conf);
return conf.pinGlobalTxToPhysicalConnection()
? new MariaDbPoolPinnedConnection(conn)
: new MariaDbPoolConnection(conn);
}

@Override
public XAConnection getXAConnection() throws SQLException {
if (conf == null) config();
return new MariaDbPoolConnection(Driver.connect(conf));
org.mariadb.jdbc.Connection conn = Driver.connect(conf);
return conf.pinGlobalTxToPhysicalConnection()
? new MariaDbPoolPinnedConnection(conn)
: new MariaDbPoolConnection(conn);
}

@Override
public XAConnection getXAConnection(String username, String password) throws SQLException {
if (conf == null) config();
Configuration conf = this.conf.clone(username, password);
return new MariaDbPoolConnection(Driver.connect(conf));
org.mariadb.jdbc.Connection conn = Driver.connect(conf);
return conf.pinGlobalTxToPhysicalConnection()
? new MariaDbPoolPinnedConnection(conn)
: new MariaDbPoolConnection(conn);
}

/**
Expand Down
116 changes: 58 additions & 58 deletions src/main/java/org/mariadb/jdbc/MariaDbPoolConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -140,67 +140,67 @@ public XAResource getXAResource() {
return new MariaDbXAResource();
}

private class MariaDbXAResource implements XAResource {

private String flagsToString(int flags) {
switch (flags) {
case TMJOIN:
return "JOIN";
case TMONEPHASE:
return "ONE PHASE";
case TMRESUME:
return "RESUME";
case TMSUSPEND:
return "SUSPEND";
default:
return "";
}
protected static XAException mapXaException(SQLException sqle) {
int xaErrorCode;

switch (sqle.getErrorCode()) {
case 1397:
xaErrorCode = XAException.XAER_NOTA;
break;
case 1398:
xaErrorCode = XAException.XAER_INVAL;
break;
case 1399:
xaErrorCode = XAException.XAER_RMFAIL;
break;
case 1400:
xaErrorCode = XAException.XAER_OUTSIDE;
break;
case 1401:
xaErrorCode = XAException.XAER_RMERR;
break;
case 1440:
xaErrorCode = XAException.XAER_DUPID;
break;
case 1402:
xaErrorCode = XAException.XA_RBROLLBACK;
break;
case 1613:
xaErrorCode = XAException.XA_RBTIMEOUT;
break;
case 1614:
xaErrorCode = XAException.XA_RBDEADLOCK;
break;
default:
xaErrorCode = 0;
break;
}
XAException xaException;
if (xaErrorCode != 0) {
xaException = new XAException(xaErrorCode);
} else {
xaException = new XAException(sqle.getMessage());
}
xaException.initCause(sqle);
return xaException;
}

private XAException mapXaException(SQLException sqle) {
int xaErrorCode;

switch (sqle.getErrorCode()) {
case 1397:
xaErrorCode = XAException.XAER_NOTA;
break;
case 1398:
xaErrorCode = XAException.XAER_INVAL;
break;
case 1399:
xaErrorCode = XAException.XAER_RMFAIL;
break;
case 1400:
xaErrorCode = XAException.XAER_OUTSIDE;
break;
case 1401:
xaErrorCode = XAException.XAER_RMERR;
break;
case 1440:
xaErrorCode = XAException.XAER_DUPID;
break;
case 1402:
xaErrorCode = XAException.XA_RBROLLBACK;
break;
case 1613:
xaErrorCode = XAException.XA_RBTIMEOUT;
break;
case 1614:
xaErrorCode = XAException.XA_RBDEADLOCK;
break;
default:
xaErrorCode = 0;
break;
}
XAException xaException;
if (xaErrorCode != 0) {
xaException = new XAException(xaErrorCode);
} else {
xaException = new XAException(sqle.getMessage());
}
xaException.initCause(sqle);
return xaException;
protected static String flagsToString(int flags) {
switch (flags) {
case XAResource.TMJOIN:
return "JOIN";
case XAResource.TMONEPHASE:
return "ONE PHASE";
case XAResource.TMRESUME:
return "RESUME";
case XAResource.TMSUSPEND:
return "SUSPEND";
default:
return "";
}
}

private class MariaDbXAResource implements XAResource {

private void execute(String command) throws XAException {
try {
Expand Down
Loading

0 comments on commit 45d8e6d

Please sign in to comment.