Search in sources :

Example 6 with FbDatabase

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);
    }
}
Also used : SQLException(java.sql.SQLException) GDSHelper(org.firebirdsql.gds.impl.GDSHelper) ResourceException(javax.resource.ResourceException) FbStatement(org.firebirdsql.gds.ng.FbStatement) FbDatabase(org.firebirdsql.gds.ng.FbDatabase) FbTransaction(org.firebirdsql.gds.ng.FbTransaction)

Example 7 with FbDatabase

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());
}
Also used : FbDatabase(org.firebirdsql.gds.ng.FbDatabase) Test(org.junit.Test)

Example 8 with FbDatabase

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);
    }
}
Also used : FBConnection(org.firebirdsql.jdbc.FBConnection) Connection(java.sql.Connection) FBConnection(org.firebirdsql.jdbc.FBConnection) GDSHelper(org.firebirdsql.gds.impl.GDSHelper) FbDatabase(org.firebirdsql.gds.ng.FbDatabase) Test(org.junit.Test)

Example 9 with FbDatabase

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);
        }
    }
}
Also used : FBConnection(org.firebirdsql.jdbc.FBConnection) TransactionParameterBuffer(org.firebirdsql.gds.TransactionParameterBuffer) FbDatabase(org.firebirdsql.gds.ng.FbDatabase) FbTransaction(org.firebirdsql.gds.ng.FbTransaction)

Example 10 with FbDatabase

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;
    }
}
Also used : FbDatabase(org.firebirdsql.gds.ng.FbDatabase) IConnectionProperties(org.firebirdsql.gds.ng.IConnectionProperties) SQLException(java.sql.SQLException)

Aggregations

FbDatabase (org.firebirdsql.gds.ng.FbDatabase)12 Test (org.junit.Test)7 FBConnection (org.firebirdsql.jdbc.FBConnection)6 SQLException (java.sql.SQLException)4 GDSHelper (org.firebirdsql.gds.impl.GDSHelper)3 IConnectionProperties (org.firebirdsql.gds.ng.IConnectionProperties)3 Connection (java.sql.Connection)2 FbTransaction (org.firebirdsql.gds.ng.FbTransaction)2 ResourceException (javax.resource.ResourceException)1 TransactionParameterBuffer (org.firebirdsql.gds.TransactionParameterBuffer)1 FbStatement (org.firebirdsql.gds.ng.FbStatement)1