How do I apply transactions to TypeORM when using it in activerecord mode?

2.3k Views Asked by At

I'm using TypeORM in active record mode and I wanted to apply transactions. In particular, I wanted each of my tests to be wrapped in a transaction, so, achieving something like this:

beforeEach(async () => {
  // start transaction
})

afterEach(async () => {
  // rollback transacttion
})

test("create new", async () => {
  // create new
}

So, I tried this:

let queryRunner: any

beforeEach(async () => {
  queryRunner = getConnection().createQueryRunner()
  await queryRunner.connect()
  await queryRunner.startTransaction()
})

afterEach(async () => {
  await queryRunner.rollbackTransaction()
  await queryRunner.release()
})

test("Create user", async () => {
  let user = new User()
  await user.save()
})

but it looks like those transactions are started on a separate context/connection, because after the test runs, I can see the record in the database.

How do I make the transaction affect the user being saved?

2

There are 2 best solutions below

1
jkulhanek On

I think you have to connect your query runner to the db. Try to modify your code as follows:

let queryRunner = getConnection().createQueryRunner()
await queryRunner.connect()
await queryRunner.startTransaction()
let user = new User()
await user.save()
await queryRunner.rollbackTransaction()
await queryRunner.release()

Also, you should use try-catch-finally block.

2
mousto090 On

instance.save() will use another queryRunner see here, this means it doesn't use the transaction you started, therefore you can't rollback user.save();

When you call user.save() COMMIT is called, you can check this by setting logging: true in the connection options.

You should run the save using the queryRunner you created, this way you can rollback

test("Create user", async () => {
    let user = new User()
    await queryRunner.manager.save(user);
})