Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prisma $transaction fails to rollback when rejectOnNotFound or *OrThrow methods are used in one of the queries #14949

Open
schongabor opened this issue Aug 23, 2022 · 4 comments
Assignees
Labels
bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. kind/bug A reported bug. team/client Issue for team Client. topic: transaction

Comments

@schongabor
Copy link

Bug description

$transaction is committed instead of being rolled back, when one of the queries fails with rejectOnNotFound: true

The function throws an error as expected, however the rollback is missing as reproduced in the code below.

Version: 3.15.2.

Likely to be an issue in the latest version as well.

How to reproduce

import { Database } from '../src/services/database';

/*
* model ReproduceTransactionIssue {
    id String @id
    value String
 }
* **/

it('Failing transaction fails to roll back with rejectOnNotFound', async () => {
  const database = new Database();
  let expectedError;

  await database.reproduceTransactionIssue.create({
    data: {
      id: 'existing_record',
      value: 'original_value',
      version: 1
    }
  });

  try {
    await database.$transaction([
      database.reproduceTransactionIssue.findFirst({
        where: {
          id: 'not_existing_record'
        },
        rejectOnNotFound: true
      }),
      database.reproduceTransactionIssue.update({
        where: {
          id: 'existing_record'
        },
        data: {
          value: 'updated_value'
        }
      })

    ]);
  } catch (error) {
    expectedError = error;
  }

  const recordsInDatabase = await database.reproduceTransactionIssue.findMany();

  expect(expectedError.name).toEqual('NotFoundError');
  expect(expectedError.message).toEqual('No ReproduceTransactionIssue found');
  expect(recordsInDatabase).toEqual([{
    id: 'existing_record',
    value: 'original_value', // this fails with updated_value
    version: 1
  }]);
});

Expected behavior

The transaction is rolled back in this case.

Prisma information

model ReproduceTransactionIssue {
  id String @id
  value String
}

Environment & setup

  • OS: Mac OS
  • Database: PostgreSQL
  • Node.js version: 16.5.0

Prisma Version

3.15.2
@schongabor schongabor added the kind/bug A reported bug. label Aug 23, 2022
@latobibor
Copy link

latobibor commented Aug 23, 2022

I can attest this does not work for me either. I have tried it with latest 4.2.1 version of @prisma/client.

There is an additional bug of rejectOnNotFound being deprecated but the suggestions are being undefined:

prisma:warn rejectOnNotFound option is deprecated and will be removed in Prisma 5. Please use prisma.survey.undefined method instead

So if you modify the above code with using findFirstOrThrow instead of findFirst({ ..., rejectOnNotFound: true }) the same problem happens.

await database.$transaction([
  // 👇 this call has been changed for Prisma 4 format
  database.reproduceTransactionIssue.findFirstOrThrow({
    where: {
      id: 'not_existing_record'
    }
  }),
  database.reproduceTransactionIssue.update({
    where: {
      id: 'existing_record'
    },
    data: {
      value: 'updated_value'
    }
  })
]);

@danstarns danstarns added topic: transaction team/client Issue for team Client. bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. labels Aug 24, 2022
@SevInf SevInf changed the title Prisma $transaction fails to rollback when rejectOnNotFound used in one of the queries Prisma $transaction fails to rollback when rejectOnNotFound or *OrThrow methods are used in one of the queries Aug 31, 2022
@SevInf
Copy link
Contributor

SevInf commented Aug 31, 2022

Hi @schongabor and @latobibor.

Thank you for the report. It is, unfortunately, a known limitation, and in case of findFirstOrThrow/findUniqueOrThrow it is documented.

Would interactive transaction workaround, mentioned in the docs be possible in your case? It should be applicable to both rejectOnNotFound and *OrThrow methods.

@latobibor
Copy link

Hi @SevInf !

Thanks for the answer and the link! In short: we can use interactive transactions. Before looking for workarounds we wanted to know if this was reported (we found similar looking ones but without a clear case/reproduction).

First we will upgrade to Prisma 4 (we are in a middle of a huge feature being implemented, we don't want to do too many steps at the same time) and then we are going to try out the interactive transactions.

@eviefp eviefp assigned eviefp and unassigned eviefp Oct 14, 2022
@miguelff
Copy link
Contributor

Tracked to try reproduce after #16226 is fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. kind/bug A reported bug. team/client Issue for team Client. topic: transaction
Projects
None yet
Development

No branches or pull requests

6 participants