$transaction<T> method

Future<T> $transaction<T>(
  1. PrismaTransactionCallback<T> callback, {
  2. TransactionOptions options = const TransactionOptions(),
  3. TransactionHeaders headers = const TransactionHeaders(),
})

Interactive transactions.

Sometimes you need more control over what queries execute within a transaction. Interactive transactions are meant to provide you with an escape hatch.

Example

final prisma = PrismaClient();
prisma.$transaction((transaction) async {
  await transaction.user.create({ ... });
  await transaction.post.create({ ... });
});

Implementation

Future<T> $transaction<T>(
  PrismaTransactionCallback<T> callback, {
  TransactionOptions options = const TransactionOptions(),
  TransactionHeaders headers = const TransactionHeaders(),
}) async {
  // If the client is a transaction, use it.
  if ($headers?.transactionId != null) {
    return callback(this);
  }

  // Request a new transaction.
  final TransactionInfo transactionInfo = await $engine.startTransaction(
    options: options,
    headers: headers,
  );

  // Create a new client for the transaction.
  final PrismaClient transactionClient = PrismaClient.fromEngine(
    $engine,
    headers: QueryEngineRequestHeaders(
      transactionId: transactionInfo.id,
      traceparent: headers.traceparent,
    ),
  );

  // Execute the transaction.
  try {
    final T result = await callback(transactionClient);
    await $engine.commitTransaction(
      headers: headers,
      info: transactionInfo,
    );
    return result;
  } catch (e) {
    await $engine.rollbackTransaction(
      headers: headers,
      info: transactionInfo,
    );
    rethrow;
  }
}