I am trying to use transactions in a typescript se...
# orm-help
t
I am trying to use transactions in a typescript service. essentially I have an optional options object argument
Copy code
options?: { $transaction?: Prisma.TransactionClient | null }
and the line
Copy code
const prisma = options?.$transaction ?? this.prisma
(where
this.prisma
is the
PrismaClient
injected into my object) unfortunately Typescript seems to think
prisma
is always the
Prisma.TransactionClient
so I can't say
if (typeof prisma.$transaction !== 'undefined')
to narrow the scope between what should be
PrismaClient | Prisma.TransactionClient
Is there any better way to conditionally run a service method in a transaction? secondary question. Is there a way given a
Prisma.TransactionClient
that I can pass in Promises similar to how I can run
prisma.$transaction([prisma.model.action(), prisma.model.action2()])
? tertiary question, why does the
Prisma.TransactionClient
not have it's own $transaction method? At the very least it could just use the currently open transaction, at best it could optionally do a nested transaction or savepoint
👀 1
a
Hey Tyler,
Is there any better way to conditionally run a service method in a transaction?
If you could share a more complete code snippet, I might be able to suggest alternative for your setup.
Is there a way given a
Prisma.TransactionClient
that I can pass in Promises similar to how I can run
prisma.$transaction([prisma.model.action(), prisma.model.action2()])
?
Not currently. When inside an interactive transaction, you would just call the Prisma methods individually since every query inside the callback is ran in a transaction anyways.
why does the
Prisma.TransactionClient
not have it’s own $transaction method?
Prisma does not support nested transactions or `SAVEPOINT`’s. Feel free to read through these existing issues and comment your use case if you would like to see this built-in. https://github.com/prisma/prisma/issues/12898 https://github.com/prisma/prisma/issues/12458
t
Copy code
export class TableNameService {
  constructor(private prisma: PrismaClient) {}

  async find(
    options?: IPagination & { $transaction?: Prisma.TransactionClient | null },
  ) {
    const { offset = 0, limit = 10 } = options ?? {};
    const prisma = options?.$transaction ?? this.prisma;

    const total = await this.count({
      $transaction: options?.$transaction,
    });
    const data = await prisma.tableName.findMany({
      skip: offset,
      take: ((limit === -1) ? undefined : limit),
    });

    return {
      offset,
      limit,
      total,
      data,
    };
  }

  async count(
    options?: { $transaction?: Prisma.TransactionClient | null },
  ) {
    const prisma = options?.$transaction ?? this.prisma;

    return prisma.tableName.count();
  }
}
is the only way I can figure out to do it, but it's messy and makes my code all polluted everywhere