Building Firebird storage support

Tags: #<Tag:0x00007fafec1eb650>

Hi Everyone,

I’ve build a Firebird storage (wil make it available when it is ready, should be in a couple of days) and everything is working fine, but I’ve got one problem/question.
Every time when the method Enqueue of the FirebirdJobQueue class is executed it was complaining about the fact that it wasn’t assigned a transaction, so I had to change the method so that I can include a transaction:

public void Enqueue(IDbTransaction transaction, string queue, string jobId)
    {
        string enqueueJobSql = string.Format(@"
            INSERT INTO ""{0}.JOBQUEUE"" (jobid, queue) 
            VALUES (@jobId, @queue);", _options.Prefix);

        _connection.Execute(enqueueJobSql, new { jobId = Convert.ToInt32(jobId, CultureInfo.InvariantCulture), queue = queue }, transaction);
    }

When I look at the PostgresSqlJobQueue, which also uses Ado.NET transactions and not the TransactionScope functionality, they don’t do this? What could be the problem?

thanks,

Rob

If you look at the SqlServer implementation, you’ll see that each call to Encueue is in-itself quueued, and will run in a transaction when Commit is called



1 Like

Thanks Pauli,

but the MS SQL Server implementation uses the TransactionScope class, the Firebird .net provider and also the PostgreSQL .net provider don’t support this class fully, so I use simple ADO.Net transactions, which are, as I understand it, not automaticly picked up by Dapper, so you have to set them explicitly. So in the FirebirdWriteOnlyTransaction class I create a ADO.net transaction in the Commit method:

public void Commit()
    {
        using (var transaction = _connection.BeginTransaction(IsolationLevel.RepeatableRead))
        {
            foreach (var command in _commandQueue)
            {
                try
                {
                    command(_connection, transaction);
                }
                catch
                {
                    throw;
                }
            }
            transaction.Commit();
        }
    }

So every command in the commandqueue will have the current transaction assigned, this is my QueueCommand method:

internal void QueueCommand(Action<FbConnection, FbTransaction> action)
    {
        _commandQueue.Enqueue(action);
    }

however the AddToQueue method goes to the FirebirdJobQueue to execute the Enqueue method, so I have to give it the current transaction, if I don’t do that, I get a error stating that there isn’t a transaction assigned to the command. This is my AddToQueue method:

public void AddToQueue(string queue, string jobId)
    {
        var provider = _queueProviders.GetProvider(queue);
        var persistentQueue = provider.GetJobQueue(_connection);

        QueueCommand((con, trx) => persistentQueue.Enqueue(trx, queue, jobId));
    }

thanks,

Rob