use of org.firebirdsql.gds.ng.FbDatabase in project jaybird by FirebirdSQL.
the class FBManagedConnectionFactory method tryCompleteInLimboTransaction.
/**
* Try to complete the "in limbo" transaction. This method tries to
* reconnect an "in limbo" transaction and complete it either by commit or
* rollback. If no "in limbo" transaction can be found, or error happens
* during completion, an exception is thrown.
*
* @param xid
* Xid of the transaction to reconnect.
* @param commit
* <code>true</code> if "in limbo" transaction should be
* committed, otherwise <code>false</code>.
*
* @throws XAException
* if "in limbo" transaction cannot be completed.
*/
private void tryCompleteInLimboTransaction(Xid xid, boolean commit) throws XAException {
try {
FBManagedConnection tempMc = null;
FirebirdLocalTransaction tempLocalTx = null;
try {
tempMc = new FBManagedConnection(null, null, this);
tempLocalTx = (FirebirdLocalTransaction) tempMc.getLocalTransaction();
tempLocalTx.begin();
long fbTransactionId = 0;
boolean found = false;
if (tempMc.getGDSHelper().compareToVersion(2, 0) < 0) {
// Find Xid by scanning
FBXid[] inLimboIds = (FBXid[]) tempMc.recover(XAResource.TMSTARTRSCAN);
for (FBXid inLimboId : inLimboIds) {
if (inLimboId.equals(xid)) {
found = true;
fbTransactionId = inLimboId.getFirebirdTransactionId();
}
}
} else {
// Find Xid by intelligent scan
FBXid foundXid = (FBXid) tempMc.findSingleXid(xid);
if (foundXid != null && foundXid.equals(xid)) {
found = true;
fbTransactionId = foundXid.getFirebirdTransactionId();
}
}
if (!found) {
throw new FBXAException((commit ? "Commit" : "Rollback") + " called with unknown transaction.", XAException.XAER_NOTA);
}
FbDatabase dbHandle = tempMc.getGDSHelper().getCurrentDatabase();
FbTransaction trHandle = dbHandle.reconnectTransaction(fbTransactionId);
// complete transaction by commit or rollback
if (commit) {
trHandle.commit();
} else {
trHandle.rollback();
}
if (tempMc.getGDSHelper().compareToVersion(3, 0) < 0) {
// remove heuristic data from rdb$transactions (only possible in versions before Firebird 3)
try {
String query = "delete from rdb$transactions where rdb$transaction_id = " + fbTransactionId;
GDSHelper gdsHelper = new GDSHelper(dbHandle);
FbTransaction trHandle2 = dbHandle.startTransaction(getDefaultTpb().getTransactionParameterBuffer());
gdsHelper.setCurrentTransaction(trHandle2);
FbStatement stmtHandle2 = dbHandle.createStatement(trHandle2);
stmtHandle2.prepare(query);
stmtHandle2.execute(RowValue.EMPTY_ROW_VALUE);
stmtHandle2.close();
trHandle2.commit();
} catch (SQLException sqle) {
throw new FBXAException("unable to remove in limbo transaction from rdb$transactions where rdb$transaction_id = " + fbTransactionId, XAException.XAER_RMERR);
}
}
} catch (SQLException ex) {
/*
* if ex.getIntParam() is 335544353 (transaction is not in limbo) and next ex.getIntParam() is 335544468 (transaction {0} is {1})
* => detected heuristic
*/
// TODO: We may need to parse the exception to get the details (or we need to handle this specific one differently)
int errorCode = XAException.XAER_RMERR;
int sqlError = ex.getErrorCode();
if (sqlError == ISCConstants.isc_no_recon) /*&& nextIntParam == ISCConstants.isc_tra_state*/
{
if (ex.getMessage().contains("committed")) {
errorCode = XAException.XA_HEURCOM;
} else if (ex.getMessage().contains("rolled back")) {
errorCode = XAException.XA_HEURCOM;
}
}
throw new FBXAException("unable to complete in limbo transaction", errorCode, ex);
} finally {
try {
if (tempLocalTx != null && tempLocalTx.inTransaction())
tempLocalTx.commit();
} finally {
if (tempMc != null)
tempMc.destroy();
}
}
} catch (ResourceException ex) {
throw new FBXAException(XAException.XAER_RMERR, ex);
}
}
use of org.firebirdsql.gds.ng.FbDatabase in project jaybird by FirebirdSQL.
the class TestJnaDatabaseConnection method identify_unconnected.
@Test
public void identify_unconnected() throws Exception {
JnaDatabaseConnection connection = new JnaDatabaseConnection(factory.getClientLibrary(), connectionInfo);
FbDatabase db = connection.identify();
assertFalse("Expected isAttached() to return false", db.isAttached());
assertThat("Expected zero-valued connection handle", db.getHandle(), equalTo(0));
assertNull("Expected version string to be null", db.getServerVersion());
assertNull("Expected version should be null", db.getServerVersion());
}
use of org.firebirdsql.gds.ng.FbDatabase in project jaybird by FirebirdSQL.
the class TestBackupManager method testRestorePageSize16384.
/**
* Test if restoring a database to page size 16384 works.
*/
@Test
public void testRestorePageSize16384() throws Exception {
usesDatabase.createDefaultDatabase();
backupManager.backupDatabase();
backupManager.setRestoreReplace(true);
backupManager.setRestorePageSize(PageSizeConstants.SIZE_16K);
backupManager.restoreDatabase();
try (Connection con = getConnectionViaDriverManager()) {
GDSHelper gdsHelper = ((FBConnection) con).getGDSHelper();
final FbDatabase currentDatabase = gdsHelper.getCurrentDatabase();
final byte[] databaseInfo = currentDatabase.getDatabaseInfo(new byte[] { ISCConstants.isc_info_page_size }, 10);
assertEquals("Unexpected info item", ISCConstants.isc_info_page_size, databaseInfo[0]);
int length = iscVaxInteger2(databaseInfo, 1);
int pageSize = iscVaxInteger(databaseInfo, 3, length);
assertEquals("Unexpected page size", 16384, pageSize);
}
}
use of org.firebirdsql.gds.ng.FbDatabase in project jaybird by FirebirdSQL.
the class TestFBMaintenanceManager method createLimboTransaction.
private void createLimboTransaction(int count) throws Exception {
try (FBConnection conn = (FBConnection) getConnectionViaDriverManager()) {
final FbDatabase fbDatabase = conn.getFbDatabase();
for (int i = 0; i < count; i++) {
TransactionParameterBuffer tpBuf = conn.createTransactionParameterBuffer();
FbTransaction transaction = fbDatabase.startTransaction(tpBuf);
transaction.prepare(null);
}
}
}
use of org.firebirdsql.gds.ng.FbDatabase in project jaybird by FirebirdSQL.
the class FBManager method dropDatabase.
@Override
public void dropDatabase(String fileName, String user, String password) throws Exception {
try {
IConnectionProperties connectionProperties = createDefaultConnectionProperties(user, password);
connectionProperties.setDatabaseName(fileName);
FbDatabase db = dbFactory.connect(connectionProperties);
db.attach();
db.dropDatabase();
} catch (Exception e) {
log.error("Exception dropping database", e);
throw e;
}
}
Aggregations