TransactionScope filter wrapper for Hangfire jobs
Registered filter will wrap jobs executed by Hangfire inside TransactionScope. Operations within a job are persisted only if there are no unhandled exceptions being thrown or job is being cancelled inside another filter.
Global level:
All jobs will be wrapped inside individual transaction scopes.
services.AddHangfire((provider, config) =>
{
config
/* Your Hangfire configuration */
.UseTransactionScope();
});
//or
GlobalConfiguration.Configuration.UseTransactionScope();
Class level:
All methods within class will be wrapped inside individual transaction scopes.
[UseTransactionScope]
public class TestService
{
public void Run1()
{
//Database writes, nested transactions etc.
}
public void Run2()
{
//Database writes, nested transactions etc.
}
}
Method level:
Only method with [UseTransactionScope]
attribute will be wrapped inside transaction scope.
public class TestService
{
[UseTransactionScope]
public void Run1()
{
//Database writes, nested transactions etc.
}
public void Run2()
{
//Some operations that maybe do not require transaction...
}
}
Default TransactionScope factory has following specs:
- TransactionScopeOption: Required
- IsolationLevel: ReadCommited
- Timeout: 1 minute
- TransactionScopeAsyncFlowOption: Enabled
You can implement ITransactionScopeFactory
to build your own TransactionScope objects.
public class CustomTransactionScopeFactory
: ITransactionScopeFactory
{
public TransactionScope CreateScope()
{
return new TransactionScope();
}
}
Register your factory on global level:
services.AddHangfire((provider, config) =>
{
config
/* Your Hangfire configuration */
.UseTransactionScope<CustomTransactionScopeFactory>();
});
//or
GlobalConfiguration.Configuration.UseTransactionScope<CustomTransactionScopeFactory>();
Register your factory per attribute:
[UseTransactionScope(typeof(CustomTransactionScopeFactory))]