Examples
Transactional Job Insertion

Insert a job within a transaction

One huge advantage of being a database-backed library is that we can insert jobs transactionally! This means that if you are in the middle of a transaction and your transaction fails, your job will be rolled back.

For example, say your application logic wants to send a email once a user is created. Here's a Prisma example to insert a job transactionally with Sidetrack's usePrisma function:

ts
import { PrismaClient } from "@prisma/client";
 
import { Sidetrack } from "sidetrack";
 
import { usePrisma } from "@sidetrack/client-prisma";
 
const prisma = new PrismaClient();
 
const sidetrack = new Sidetrack<{
userOnboarding: { email: string };
}>({
databaseOptions: {
connectionString: process.env["DATABASE_URL"]!,
},
queues: {
userOnboarding: {
handler: async (job) => {
console.log(`Welcome ${job.payload.email}`);
},
},
},
});
 
// In this transaction, we're creating both the user and background job
prisma.$transaction(async (prismaTx) => {
const user = await prismaTx.user.create(/* create your user */);
return sidetrack.insertJob(
"userOnboarding",
{
email: user.email,
},
{ dbClient: usePrisma(prismaTx) },
);
});
 
// if you run other application code which fails, the entire transaction will rollback
// and neither the job nor user will be inserted!
prisma.$transaction(async (prismaTx) => {
const user = await prismaTx.user.create(/* create your user */);
await sidetrack.insertJob(
"userOnboarding",
{
email: user.email,
},
{ dbClient: usePrisma(prismaTx) },
);
throw new Error("Something went wrong");
});
ts
import { PrismaClient } from "@prisma/client";
 
import { Sidetrack } from "sidetrack";
 
import { usePrisma } from "@sidetrack/client-prisma";
 
const prisma = new PrismaClient();
 
const sidetrack = new Sidetrack<{
userOnboarding: { email: string };
}>({
databaseOptions: {
connectionString: process.env["DATABASE_URL"]!,
},
queues: {
userOnboarding: {
handler: async (job) => {
console.log(`Welcome ${job.payload.email}`);
},
},
},
});
 
// In this transaction, we're creating both the user and background job
prisma.$transaction(async (prismaTx) => {
const user = await prismaTx.user.create(/* create your user */);
return sidetrack.insertJob(
"userOnboarding",
{
email: user.email,
},
{ dbClient: usePrisma(prismaTx) },
);
});
 
// if you run other application code which fails, the entire transaction will rollback
// and neither the job nor user will be inserted!
prisma.$transaction(async (prismaTx) => {
const user = await prismaTx.user.create(/* create your user */);
await sidetrack.insertJob(
"userOnboarding",
{
email: user.email,
},
{ dbClient: usePrisma(prismaTx) },
);
throw new Error("Something went wrong");
});