Search code examples
rubyfirebird

What is the meaning of "Fb::Error: A transaction has already been started"


I have a Ruby application that crashes sometimes with this error message:

Fb::Error: A transaction has already been started)

I'm now wondering what this message means. I searched a little bit and I read that Firebird is not supporting nested transactions. Could the message hint to this? If not, what else could this mean?


Solution

  • This is not a Firebird error message. It is an error message in the driver you're using. Specifically here:

    static void fb_connection_transaction_start(struct FbConnection *fb_connection, VALUE opt)
    {
        char *tpb = 0;
        long tpb_len;
    
        if (fb_connection->transact) {
            rb_raise(rb_eFbError, "A transaction has been already started");
        }
    
        if (!NIL_P(opt)) {
            tpb = trans_parseopts(opt, &tpb_len);
        } else {
            tpb_len = 0;
            tpb = NULL;
        }
    
        isc_start_transaction(fb_connection->isc_status, &fb_connection->transact, 1, &fb_connection->db, tpb_len, tpb);
        xfree(tpb);
        fb_error_check(fb_connection->isc_status);
    }
    

    Without in-depth familiarity with this driver, I'm guessing the problem is that you're trying to start a transaction on a connection that already has an active transaction.

    Firebird itself supports multiple parallel transactions on a single connection, and it supports nested transactions in the form of SQL standard savepoints, but it looks like the driver you're using doesn't support this.

    The solution (or workaround) would seem to be to either not start a transaction when you already have an active transaction, or to first commit or rollback an existing transaction before starting a new one.