TypeORM - Transactions



Generally, transaction is a logic unit responsible for execution of data retrieval and updates. This section explains about Transactions in detail.

Creating transactions

We can create a transaction using either connection or EntityManage. Below example is used to specify create connection and save data inside it.

import {getConnection} from "typeorm"; 
await getConnection().transaction(async transactionalEntityManager => { 
   await connection.manager.save(students); 
});

EntityManager is shown below −

import {getManager} from "typeorm";

await getManager().transaction(async transactionalEntityManager => { 
   await transactionalEntityManager.save(students); 
});

Decorators

We have three types of transaction related decorators in TypeORM.

  • @Transaction - Wraps all the execution in single database transcation.
  • @TransactionManager - Used to execute queries inside transaction. It is defined below,
@Transaction({ isolation: "SERIALIZABLE" }) 

save(@TransactionManager() manager: EntityManager, student: Student) {     
   return manager.save(student); 
}

Here,

We used SERIALIZABLE isolation level for transaction.

  • @TransactionRepository - Used to inject transaction in repository. It is defined below,
@Transaction() save(student: Student, @TransactionRepository(Student) studentRepository: 
Repository<Student>) { 
   return studentRepository.save(student); 
}

Transaction in QueryRunner

QueryRunner is used to execute all database queries. It has single database connection. Database transaction can be organized using QueryRunner. Let’s perform single transaction using QueryRunner.

import {getConnection} from "typeorm"; 

// get a connection and create a new query runner 
const connection = getConnection(); const queryRunner = connection.createQueryRunner(); 

// establish real database connection using our new query runner 
await queryRunner.connect(); 

// now we can execute any queries on a query runner, for example: await queryRunner.query("SELECT * FROM students");

Now, start transaction using the below statement −

await queryRunner.startTransaction();

Then, commit and rollback the transaction using the below statement,

try { 
   await queryRunner.commitTransaction(); 
}

If there is any error, it is handled by catch(),

catch (err) { 

   // since we have errors lets rollback changes we made await queryRunner.rollbackTransaction(); 
}

Now, release the queryRunner as below −

finally { 
   
   // you need to release query runner which is manually created: await queryRunner.release(); 
}
Advertisements