Транзакции
Эта страница переведена PageTurner AI (бета). Не одобрена официально проектом. Нашли ошибку? Сообщить о проблеме →
Создание и использование транзакций
Транзакции создаются с помощью DataSource или EntityManager.
Примеры:
await myDataSource.transaction(async (transactionalEntityManager) => {
// execute queries using transactionalEntityManager
})
или
await myDataSource.manager.transaction(async (transactionalEntityManager) => {
// execute queries using transactionalEntityManager
})
Всё, что должно выполняться в транзакции, необходимо поместить в колбэк:
await myDataSource.manager.transaction(async (transactionalEntityManager) => {
await transactionalEntityManager.save(users)
await transactionalEntityManager.save(photos)
// ...
})
Ключевое ограничение при работе в транзакции — ВСЕГДА используйте предоставленный экземпляр менеджера сущностей
(в примере это transactionalEntityManager). НЕ ИСПОЛЬЗУЙТЕ ГЛОБАЛЬНЫЙ МЕНЕДЖЕР СУЩНОСТЕЙ.
ВСЕ операции ДОЛЖНЫ выполняться через предоставленный транзакционный менеджер сущностей.
Указание уровней изоляции
Уровень изоляции транзакции можно задать через первый параметр:
await myDataSource.manager.transaction(
"SERIALIZABLE",
(transactionalEntityManager) => {},
)
Реализации уровней изоляции не являются универсальными для всех баз данных. Каждый драйвер объявляет поддерживаемые уровни, и TypeORM выбросит ошибку при запросе неподдерживаемого уровня.
| Driver | Supported isolation levels |
|---|---|
| MySQL / MariaDB | READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE |
| PostgreSQL | READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE |
| CockroachDB | READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE |
| SQL Server | READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE, SNAPSHOT |
| Oracle | READ COMMITTED, SERIALIZABLE |
| SAP HANA | READ COMMITTED, REPEATABLE READ, SERIALIZABLE |
| SQLite | READ UNCOMMITTED*, SERIALIZABLE |
| Spanner | READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE |
* READ UNCOMMITTED в SQLite применяется только при включённом режиме shared-cache. В стандартном режиме SQLite всегда использует изоляцию SERIALIZABLE независимо от настройки.
SQL Server также поддерживает установку уровня изоляции по умолчанию через опции источника данных (isolationLevel и connectionIsolationLevel), но они подвержены ограничению пула соединений. Уровни изоляции отдельных транзакций не затрагиваются.
Использование QueryRunner для управления состоянием подключения к БД
QueryRunner предоставляет единое подключение к базе данных.
Транзакции организуются через query runner.
Каждая транзакция привязана к конкретному экземпляру query runner.
Вы можете вручную создать экземпляр query runner для управления состоянием транзакции.
Пример:
// create a new query runner
const queryRunner = dataSource.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 users")
// we can also access entity manager that works with connection created by a query runner:
const users = await queryRunner.manager.find(User)
// lets now open a new transaction:
await queryRunner.startTransaction()
try {
// execute some operations on this transaction:
await queryRunner.manager.save(user1)
await queryRunner.manager.save(user2)
await queryRunner.manager.save(photos)
// commit transaction now:
await queryRunner.commitTransaction()
} catch (err) {
// since we have errors let's rollback changes we made
await queryRunner.rollbackTransaction()
} finally {
// you need to release query runner which is manually created:
await queryRunner.release()
}
В QueryRunner доступны 3 метода управления транзакциями:
-
startTransaction- начинает новую транзакцию в экземпляре query runner. -
commitTransaction- фиксирует все изменения, выполненные с помощью экземпляра query runner. -
rollbackTransaction- откатывает все изменения, выполненные с помощью экземпляра query runner.
Подробнее в разделе Query Runner.