Skip to content

Commit

Permalink
JDBC-464 fix java.sql.SQLNonTransientException: No transaction or tra…
Browse files Browse the repository at this point in the history
…nsaction not ACTIVE for ResultSetMetaData.getPrecision
  • Loading branch information
mrotteveel committed Dec 11, 2016
1 parent 2a9c215 commit fb66511
Show file tree
Hide file tree
Showing 15 changed files with 103 additions and 122 deletions.
9 changes: 4 additions & 5 deletions src/jdbc_41/org/firebirdsql/jdbc/FBResultSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
*/
package org.firebirdsql.jdbc;

import org.firebirdsql.gds.impl.GDSHelper;
import org.firebirdsql.gds.ng.FbStatement;
import org.firebirdsql.gds.ng.fields.RowDescriptor;
import org.firebirdsql.gds.ng.fields.RowValue;
Expand All @@ -39,10 +38,10 @@
*/
public class FBResultSet extends AbstractResultSet {

public FBResultSet(GDSHelper gdsHelper, FBStatement fbStatement, FbStatement stmt,
public FBResultSet(FBConnection connection, FBStatement fbStatement, FbStatement stmt,
FBObjectListener.ResultSetListener listener, boolean metaDataQuery, int rsType, int rsConcurrency,
int rsHoldability, boolean cached) throws SQLException {
super(gdsHelper, fbStatement, stmt, listener, metaDataQuery, rsType, rsConcurrency, rsHoldability, cached);
super(connection, fbStatement, stmt, listener, metaDataQuery, rsType, rsConcurrency, rsHoldability, cached);
}

public FBResultSet(RowDescriptor rowDescriptor, List<RowValue> rows, FBObjectListener.ResultSetListener listener)
Expand All @@ -54,8 +53,8 @@ public FBResultSet(RowDescriptor rowDescriptor, List<RowValue> rows) throws SQLE
super(rowDescriptor, rows);
}

public FBResultSet(RowDescriptor rowDescriptor, GDSHelper gdsHelper, List<RowValue> rows, boolean retrieveBlobs)
public FBResultSet(RowDescriptor rowDescriptor, FBConnection connection, List<RowValue> rows, boolean retrieveBlobs)
throws SQLException {
super(rowDescriptor, gdsHelper, rows, retrieveBlobs);
super(rowDescriptor, connection, rows, retrieveBlobs);
}
}
9 changes: 4 additions & 5 deletions src/jdbc_42/org/firebirdsql/jdbc/FBResultSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
*/
package org.firebirdsql.jdbc;

import org.firebirdsql.gds.impl.GDSHelper;
import org.firebirdsql.gds.ng.FbStatement;
import org.firebirdsql.gds.ng.fields.RowDescriptor;
import org.firebirdsql.gds.ng.fields.RowValue;
Expand All @@ -40,10 +39,10 @@
*/
public class FBResultSet extends AbstractResultSet {

public FBResultSet(GDSHelper gdsHelper, FBStatement fbStatement, FbStatement stmt,
public FBResultSet(FBConnection connection, FBStatement fbStatement, FbStatement stmt,
FBObjectListener.ResultSetListener listener, boolean metaDataQuery, int rsType, int rsConcurrency,
int rsHoldability, boolean cached) throws SQLException {
super(gdsHelper, fbStatement, stmt, listener, metaDataQuery, rsType, rsConcurrency, rsHoldability, cached);
super(connection, fbStatement, stmt, listener, metaDataQuery, rsType, rsConcurrency, rsHoldability, cached);
}

public FBResultSet(RowDescriptor rowDescriptor, List<RowValue> rows, FBObjectListener.ResultSetListener listener)
Expand All @@ -55,9 +54,9 @@ public FBResultSet(RowDescriptor rowDescriptor, List<RowValue> rows) throws SQLE
super(rowDescriptor, rows);
}

public FBResultSet(RowDescriptor rowDescriptor, GDSHelper gdsHelper, List<RowValue> rows, boolean retrieveBlobs)
public FBResultSet(RowDescriptor rowDescriptor, FBConnection connection, List<RowValue> rows, boolean retrieveBlobs)
throws SQLException {
super(rowDescriptor, gdsHelper, rows, retrieveBlobs);
super(rowDescriptor, connection, rows, retrieveBlobs);
}

/**
Expand Down
12 changes: 0 additions & 12 deletions src/main/org/firebirdsql/gds/impl/GDSHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -173,18 +173,6 @@ public FbTransaction startTransaction(TransactionParameterBuffer tpb) throws SQL
return transaction;
}

public void prepareTransaction(FbTransaction transaction, byte[] message) throws SQLException {
transaction.prepare(message);
}

public void commitTransaction(FbTransaction transaction) throws SQLException {
transaction.commit();
}

public void rollbackTransaction(FbTransaction transaction) throws SQLException {
transaction.rollback();
}

public void detachDatabase() throws SQLException {
database.close();
}
Expand Down
10 changes: 5 additions & 5 deletions src/main/org/firebirdsql/jca/FBManagedConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -645,11 +645,11 @@ void internalCommit(Xid xid, boolean onePhase) throws XAException {
// TODO Equivalent or handled by listeners?
//committingTr.forgetResultSets();

getGDSHelper().commitTransaction(committingTr);
committingTr.commit();
} catch (SQLException ge) {
if (gdsHelper != null) {
try {
gdsHelper.rollbackTransaction(committingTr);
committingTr.rollback();
} catch (SQLException ge2) {
if (log != null) log.debug("Exception rolling back failed tx: ", ge2);
}
Expand Down Expand Up @@ -890,11 +890,11 @@ int internalPrepare(Xid xid) throws FBXAException {
}
byte[] message = fbxid.toBytes();

getGDSHelper().prepareTransaction(committingTr, message);
committingTr.prepare(message);
} catch (SQLException ge) {
try {
if (gdsHelper != null) {
gdsHelper.rollbackTransaction(committingTr);
committingTr.rollback();
} else if (log != null) {
log.warn("Unable to rollback failed tx, connection closed or lost");
}
Expand Down Expand Up @@ -1128,7 +1128,7 @@ void internalRollback(Xid xid) throws XAException {
// TODO Equivalent needed or handled by listeners?
//committingTr.forgetResultSets();
try {
getGDSHelper().rollbackTransaction(committingTr);
committingTr.rollback();
} finally {
xidMap.remove(xid);
preparedXid.remove(xid);
Expand Down
4 changes: 2 additions & 2 deletions src/main/org/firebirdsql/jdbc/AbstractCallableStatement.java
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public ParameterMetaData getParameterMetaData() throws SQLException {
prepareFixedStatement(procedureCall.getSQL(isSelectableProcedure()));
}

return new FBParameterMetaData(fbStatement.getParameterDescriptor(), gdsHelper);
return new FBParameterMetaData(fbStatement.getParameterDescriptor(), connection);
}

public void addBatch() throws SQLException {
Expand Down Expand Up @@ -348,7 +348,7 @@ protected boolean internalExecute(boolean sendOutParams) throws SQLException {
final boolean hasResultSet = super.internalExecute(sendOutParams);
if (hasResultSet && isSingletonResult) {
// Safeguarding first row so it will work even if the result set from getResultSet is manipulated
singletonRs = new FBResultSet(fbStatement.getFieldDescriptor(), gdsHelper,
singletonRs = new FBResultSet(fbStatement.getFieldDescriptor(), connection,
new ArrayList<>(specialResult), true);
}
return hasResultSet;
Expand Down
11 changes: 5 additions & 6 deletions src/main/org/firebirdsql/jdbc/AbstractFieldMetaData.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

import org.firebirdsql.encodings.EncodingDefinition;
import org.firebirdsql.gds.ISCConstants;
import org.firebirdsql.gds.impl.GDSHelper;
import org.firebirdsql.gds.ng.fields.FieldDescriptor;
import org.firebirdsql.gds.ng.fields.RowDescriptor;
import org.firebirdsql.jdbc.field.JdbcTypeConverter;
Expand All @@ -44,13 +43,13 @@ public abstract class AbstractFieldMetaData implements Wrapper {
private static final int SUBTYPE_DECIMAL = 2;

private final RowDescriptor rowDescriptor;
private final GDSHelper gdsHelper;
private final FBConnection connection;
private Map<FieldKey, ExtendedFieldInfo> extendedInfo;

protected AbstractFieldMetaData(RowDescriptor rowDescriptor, GDSHelper gdsHelper) {
protected AbstractFieldMetaData(RowDescriptor rowDescriptor, FBConnection connection) {
assert rowDescriptor != null : "rowDescriptor is required";
this.rowDescriptor = rowDescriptor;
this.gdsHelper = gdsHelper;
this.connection = connection;
}

@Override
Expand Down Expand Up @@ -339,7 +338,7 @@ protected final int estimateFixedPrecision(int fieldIndex) {

protected final ExtendedFieldInfo getExtFieldInfo(int columnIndex) throws SQLException {
if (extendedInfo == null) {
extendedInfo = getExtendedFieldInfo(gdsHelper);
extendedInfo = getExtendedFieldInfo(connection);
}

FieldKey key = new FieldKey(
Expand All @@ -358,7 +357,7 @@ protected final ExtendedFieldInfo getExtFieldInfo(int columnIndex) throws SQLExc
* @throws SQLException
* if a database error occurs while obtaining extended field information.
*/
protected abstract Map<FieldKey, ExtendedFieldInfo> getExtendedFieldInfo(GDSHelper gdsHelper) throws SQLException;
protected abstract Map<FieldKey, ExtendedFieldInfo> getExtendedFieldInfo(FBConnection connection) throws SQLException;

/**
* This class is an old-fashion data structure that stores additional
Expand Down
4 changes: 2 additions & 2 deletions src/main/org/firebirdsql/jdbc/AbstractPreparedStatement.java
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ public int executeUpdate() throws SQLException {
}

public FirebirdParameterMetaData getFirebirdParameterMetaData() throws SQLException {
return new FBParameterMetaData(fbStatement.getParameterDescriptor(), gdsHelper);
return new FBParameterMetaData(fbStatement.getParameterDescriptor(), connection);
}

/**
Expand Down Expand Up @@ -1097,7 +1097,7 @@ public void setArray(int i, Array x) throws SQLException {
*/
public ResultSetMetaData getMetaData() throws SQLException {
checkValidity();
return new FBResultSetMetaData(fbStatement.getFieldDescriptor(), gdsHelper);
return new FBResultSetMetaData(fbStatement.getFieldDescriptor(), connection);
}

/**
Expand Down
22 changes: 11 additions & 11 deletions src/main/org/firebirdsql/jdbc/AbstractResultSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public abstract class AbstractResultSet implements ResultSet, FirebirdResultSet,
private FBFetcher fbFetcher;
private FirebirdRowUpdater rowUpdater;

protected final FBConnection connection;
protected final GDSHelper gdsHelper;

protected final RowDescriptor rowDescriptor;
Expand Down Expand Up @@ -93,12 +94,8 @@ public void rowChanged(FBFetcher fetcher, RowValue newRow) throws SQLException {

/**
* Creates a new <code>FBResultSet</code> instance.
*
* @param gdsHelper a <code>AbstractConnection</code> value
* @param fbStatement a <code>AbstractStatement</code> value
* @param stmt an <code>isc_stmt_handle</code> value
*/
public AbstractResultSet(GDSHelper gdsHelper,
public AbstractResultSet(FBConnection connection,
FBStatement fbStatement,
FbStatement stmt,
FBObjectListener.ResultSetListener listener,
Expand All @@ -108,7 +105,8 @@ public AbstractResultSet(GDSHelper gdsHelper,
int rsHoldability,
boolean cached)
throws SQLException {
this.gdsHelper = gdsHelper;
this.connection = connection;
this.gdsHelper = connection != null ? connection.getGDSHelper() : null;
cursorName = fbStatement.getCursorName();
this.listener = listener != null ? listener : FBObjectListener.NoActionResultSetListener.instance();
trimStrings = metaDataQuery;
Expand Down Expand Up @@ -142,7 +140,7 @@ public AbstractResultSet(GDSHelper gdsHelper,

if (rsConcurrency == ResultSet.CONCUR_UPDATABLE) {
try {
rowUpdater = new FBRowUpdater(gdsHelper, rowDescriptor, this, cached, listener);
rowUpdater = new FBRowUpdater(connection, rowDescriptor, this, cached, listener);
} catch (FBResultSetNotUpdatableException ex) {
fbStatement.addWarning(FbExceptionBuilder
.forException(JaybirdErrorCodes.jb_concurrencyResetReadOnlyReasonNotUpdatable)
Expand Down Expand Up @@ -170,6 +168,7 @@ public AbstractResultSet(GDSHelper gdsHelper,
*/
public AbstractResultSet(RowDescriptor rowDescriptor, List<RowValue> rows, FBObjectListener.ResultSetListener listener) throws SQLException {
// TODO Evaluate if we need to share more implementation with constructor above
connection = null;
gdsHelper = null;
fbStatement = null;
this.listener = listener != null ? listener : FBObjectListener.NoActionResultSetListener.instance();
Expand Down Expand Up @@ -213,14 +212,15 @@ public AbstractResultSet(RowDescriptor rowDescriptor, List<RowValue> rows) throw
* </p>
*
* @param rowDescriptor Column definition
* @param gdsHelper GDS Helper (cannot be null when {@code retrieveBlobs} is {@code true}
* @param connection Connection (cannot be null when {@code retrieveBlobs} is {@code true}
* @param rows Row data
* @param retrieveBlobs {@code true} retrieves the blob data
* @throws SQLException
*/
public AbstractResultSet(RowDescriptor rowDescriptor, GDSHelper gdsHelper, List<RowValue> rows,
public AbstractResultSet(RowDescriptor rowDescriptor, FBConnection connection, List<RowValue> rows,
boolean retrieveBlobs) throws SQLException {
this.gdsHelper = gdsHelper;
this.connection = connection;
this.gdsHelper = connection != null ? connection.getGDSHelper() : null;
fbStatement = null;
listener = FBObjectListener.NoActionResultSetListener.instance();
cursorName = null;
Expand Down Expand Up @@ -1104,7 +1104,7 @@ public String getCursorName() throws SQLException {
* this result set is constructed in code.
*/
public ResultSetMetaData getMetaData() throws SQLException {
return new FBResultSetMetaData(rowDescriptor, gdsHelper);
return new FBResultSetMetaData(rowDescriptor, connection);
}

/**
Expand Down
64 changes: 35 additions & 29 deletions src/main/org/firebirdsql/jdbc/FBDatabaseMetaData.java
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,6 @@ public class FBDatabaseMetaData implements FirebirdDatabaseMetaData {

protected final Map<String, FBPreparedStatement> statements = new HashMap<>();

protected FBDatabaseMetaData(GDSHelper gdsHelper) {
this.gdsHelper = gdsHelper;
firebirdSupportInfo = supportInfoFor(gdsHelper.getCurrentDatabase());
}

protected FBDatabaseMetaData(FBConnection c) throws SQLException {
this.gdsHelper = c.getGDSHelper();
this.connection = c;
Expand Down Expand Up @@ -4949,9 +4944,9 @@ public String getProcedureSourceCode(String procedureName) throws SQLException {
+ "RDB$PROCEDURE_NAME = ?";
List<String> params = new ArrayList<>();
params.add(procedureName);
ResultSet rs = doQuery(sql, params);
if (rs.next()) sResult = rs.getString(1);
rs.close();
try (ResultSet rs = doQuery(sql, params)) {
if (rs.next()) sResult = rs.getString(1);
}

return sResult;
}
Expand All @@ -4961,9 +4956,9 @@ public String getTriggerSourceCode(String triggerName) throws SQLException {
String sql = "Select RDB$TRIGGER_SOURCE From RDB$TRIGGERS Where RDB$TRIGGER_NAME = ?";
List<String> params = new ArrayList<>();
params.add(triggerName);
ResultSet rs = doQuery(sql, params);
if (rs.next()) sResult = rs.getString(1);
rs.close();
try (ResultSet rs = doQuery(sql, params)) {
if (rs.next()) sResult = rs.getString(1);
}

return sResult;
}
Expand All @@ -4973,9 +4968,9 @@ public String getViewSourceCode(String viewName) throws SQLException {
String sql = "Select RDB$VIEW_SOURCE From RDB$RELATIONS Where RDB$RELATION_NAME = ?";
List<String> params = new ArrayList<>();
params.add(viewName);
ResultSet rs = doQuery(sql, params);
if (rs.next()) sResult = rs.getString(1);
rs.close();
try (ResultSet rs = doQuery(sql, params)) {
if (rs.next()) sResult = rs.getString(1);
}

return sResult;
}
Expand Down Expand Up @@ -5017,7 +5012,7 @@ protected static byte[] getBytes(String value){
return value != null ? value.getBytes(StandardCharsets.UTF_8): null;
}

private FBPreparedStatement getStatement(String sql) throws SQLException {
private FBPreparedStatement getStatement(String sql, boolean standalone) throws SQLException {
FBPreparedStatement s = statements.get(sql);

if (s != null) {
Expand All @@ -5028,19 +5023,16 @@ private FBPreparedStatement getStatement(String sql) throws SQLException {
}
}

if (connection == null) {
InternalTransactionCoordinator.MetaDataTransactionCoordinator metaDataTransactionCoordinator =
new InternalTransactionCoordinator.MetaDataTransactionCoordinator();
InternalTransactionCoordinator.MetaDataTransactionCoordinator metaDataTransactionCoordinator =
new InternalTransactionCoordinator.MetaDataTransactionCoordinator(connection.txCoordinator);

s = new FBPreparedStatement(gdsHelper, sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY,
ResultSet.CLOSE_CURSORS_AT_COMMIT, metaDataTransactionCoordinator, metaDataTransactionCoordinator,
true, true, false);
} else {
s = (FBPreparedStatement)connection.prepareMetaDataStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
}
s = new FBPreparedStatement(gdsHelper, sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY,
ResultSet.CLOSE_CURSORS_AT_COMMIT, metaDataTransactionCoordinator, metaDataTransactionCoordinator,
true, standalone, false);

statements.put(sql, s);
if (!standalone) {
statements.put(sql, s);
}

return s;
}
Expand All @@ -5055,10 +5047,24 @@ private FBPreparedStatement getStatement(String sql) throws SQLException {
* @throws SQLException
* if a database access error occurs
*/
protected ResultSet doQuery(String sql, List<String> params)
throws SQLException {
protected ResultSet doQuery(String sql, List<String> params) throws SQLException {
return doQuery(sql, params, false);
}

FBPreparedStatement s = getStatement(sql);
/**
* Execute an sql query with a given set of parameters.
*
* @param sql
* The sql statement to be used for the query
* @param params
* The parameters to be used in the query
* @param standalone
* The query to be executed is a standalone query (should not be cached and be closed asap)
* @throws SQLException
* if a database access error occurs
*/
protected ResultSet doQuery(String sql, List<String> params, boolean standalone) throws SQLException {
FBPreparedStatement s = getStatement(sql, standalone);

for (int i = 0; i < params.size(); i++)
s.setStringForced(i + 1, params.get(i));
Expand Down
Loading

0 comments on commit fb66511

Please sign in to comment.