Skip to content

Getting started

XactJobs lets you schedule and run background jobs with full database transaction support using Entity Framework Core. Jobs are saved alongside your business data and only execute if your transaction commits: no “ghost” jobs on rollback.

It supports SQL Server, PostgreSQL, MySQL, Oracle and SQLite, on .NET 8, 9 and 10. XactJobs uses EF Core 9 on .NET 8 and 9, and EF Core 10 on .NET 10, so your database provider has to support that version. For MySQL, see which provider to use.

Terminal window
dotnet add package XactJobs

Your app also needs the EF Core provider of its database, registered as usual. The provider isn’t part of XactJobs:

// Microsoft.EntityFrameworkCore.SqlServer
builder.Services.AddDbContext<UserDbContext>(options =>
options.UseSqlServer(connectionString));

For a new installation, run the install script for your database. It creates the latest schema: the job table, the history and the periodic jobs.

sql/install/xact-jobs-sqlserver.sql creates the tables in the XactJobs schema.

Run it with QUOTED_IDENTIFIER and ANSI_NULLS on, which are SqlClient’s and SSMS’s defaults (sqlcmd needs -I): the job table has a filtered index.

All the scripts are in sql/. To upgrade an existing installation, run the versioned scripts instead: see Upgrading.

Instead of the scripts, you can include the XactJobs entities in your EF migrations:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyXactJobsConfigurations(Database.ProviderName,
excludeFromMigrations: false); // <--- key part here
// Apply your entity configurations...
}

And then create the migration like you normally would:

Terminal window
dotnet ef migrations add XactJobsTables

Add the entity configurations to your DbContext:

public class UserDbContext : DbContext
{
public UserDbContext(DbContextOptions<UserDbContext> options) : base(options)
{
}
// Your DbSets...
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyXactJobsConfigurations(Database.ProviderName);
// Apply your entity configurations...
}
}

Register XactJobs in Program.cs. The workers run as hosted services in your app:

// This registers 2 workers for the default queue
builder.Services.AddXactJobs<UserDbContext>(options =>
{
options.WithPriorityQueue(); // optional (2 additional workers)
options.WithLongRunningQueue(); // optional (2 additional workers)
});

All the options are in the configuration reference.

A job is a public method. Enqueue it on your DbContext, next to your business data, and save. JobEnqueue and the other methods are extension methods in the XactJobs namespace (using XactJobs;):

public static class Greeter
{
public static void Say(string message) => Console.WriteLine(message);
}
// ... other business logic
dbContext.JobEnqueue(
() => Greeter.Say("Fire-and-forget!"));
dbContext.SaveChanges();

The job is a row in the same transaction as your changes. If the transaction commits, a worker runs it; if it rolls back, the job doesn’t exist.

  1. Read Jobs for what a job method can be, and how instance methods get their dependencies.
  2. Read A job is a unit of work: the worker saves a job’s database changes, not the job.
  3. Add the dashboard to see and manage the jobs.