Open dweggemans opened 7 years ago
I have found no easy solution since commands are not automatically enlisted in local pending transactions. See https://github.com/dotnet/corefx/issues/13927 This means you have to pass the existing transaction around to assign it to the command.
Ultimate goal is to save changes together with one or more background jobs in a single transaction.
Have you considered to start a database transaction, and create a background job just before committing it?
using (var transaction = postgres.BeginTransaction())
{
var entityId = transaction.CreateEntity();
BackgroundJob.Enqueue(() => ProcessEntity(entityId));
transaction.Commit();
}
When executing actions like this, you could expect the following behaviors:
public static void ProcessEntity(int entityId)
{
using (var transaction = Database.BeginTransaction(IsolationLevel.ReadCommitted))
{
var entity = transaction.GetEntity(entityId);
if (entity == null) return;
// Process entity
}
}
That shouldn't be a big problem, because background jobs sometimes are delayed to minutes, hours and days, and they should be robust enough to deal with non-existing records.
I've considered it, but rejected the idea because it is error prone (this is coded in a base library which is used by many components) to have all handlers perform these checks. Besides that it has performance impact.
What I did as a workaround is that I've subclassed 'SqlServerStorage' to return a custom connection that wraps the SqlServerConnection
and override the CreateExpiredJob to use the existing transaction.
Additionally I had to override CreateWriteTransaction to return a custom JobStorageTransaction
which also uses the existing transaction on the few methods that are used to create a job. The only reason to do this is to prevent it from actually starting a transaction (which I couldn't, so I had to override the methods that create and update jobs not to start another transaction).
Not the most elegant, but it works. The downside is that I now have a direct dependency on the Hangfire database schema.
I am trying to use Hangfire with an existing connection and transaction. Ultimate goal is to save changes together with one or more background jobs in a single transaction.
This fails because the transaction is not set on the SQL commands executed by Hangfire. I assume this would work on the full framework because one can use a TransactionScope and the SQL commands would auto enlist in the ambient transaction? This is not an option on .NET Core though.
Exception details
Steps to reproduce