Documentation chapters
You're looking at legacy documentation.
New multi-language documentation available at https://docs.deepkit.io
ORM

Transaction

A transaction is a sequential group of statements, queries, or operations such as select, insert, update or delete to perform as a one single work unit that can be committed or rolled back.

Deepkit supports transactions for all official supported databases. By default for each query and database session no transactions are used. To enable transactions there are two main methods.

Session

You can start and assign on each created session a new transaction. This is the preferred way of interacting with the database, as you can easily pass around the session object and all queries instantiated from that session object are automatically assigned to its transaction.

A typical pattern is to wrap all operations in a try-catch block and execute commit() in the very last line (that is only executed when all previous commands succeeded) and rollback() in the catch block to roll back all changes.

Although there is an alternative API (see below), all transactions work only with database session objects. Usually, to commit open changes from the unit-of-work in a database session to the database, you would call commit(). In a transactional session, commit() not only flushes all pending changes to the database but also closes ("commits") the transaction, essentially closing the transaction. As an alternative, you can call session.flush() to flush all pending changes without commit and thus without closing the transaction. To commit a transaction without flushing the unit-of-work, use session.commitTransaction().

const session = database.createSession();

//this assigns a new transaction, and starts it with the very next database operation.
session.useTransaction();

try {
    //this query is executed in the transaction
    const users = await session.query(User).find();

    await moreDatabaseOperations(session);

    await session.commit();
} catch (error) {
    await session.rollback();
}

As soon as commit() or rollback() is executed on a session, the transaction is released. You have to call useTransaction() again if you want to continue working in a new transaction.

Please note, that as soon as the first database operation is executed in a transactional session, the assigned database connection to this operation is assigned (sticky) to the current session object, and thus, all subsequent operations are executed on the same connection (and thus, in most databases, on the same database server).

If a session is already associated with a transaction, a call to session.useTransaction() always returns the same object. Use session.isTransaction() to check whether the session has a transaction assigned.

Nested transactions are not supported.

Callback

An alternative to transactional sessions is database.transaction(callback).

await database.transaction(async (session) => {
    //this query is executed in the transaction
    const users = await session.query(User).find();

    await moreDatabaseOperations(session);
});

The method transaction(callback) executes an async callback inside of a new transactional session. If the callback succeeds (not throwing), the session is automatically committed (and thus its transaction committed and all changes flushed). If the callback throws, the session executes rollback() automatically, and the error is rethrown.

Transaction isolation

Many databases support different kinds of transactions. To change the transaction behavior, you can call various methods on the returned transaction object from useTransaction(). The interface of this transaction object depends on the database adapter being used. For example, the transaction object returned from a MySQL database has different options from one returned from a MongoDB database. Use code-completion or look at the database adapter interface to get a list of potential options.

const database = new Database(new MySQLDatabaseAdapter());

const session = database.createSession();
session.useTransaction().readUncommitted();

try {
    //...operations
    await session.commit();
} catch () {
    await session.rollback();
}

//or
await database.transaction(async (session) => {
    //this works as long as no database operation has been exuected.
    session.useTransaction().readUncommitted();

    //...operations
});

MongoDB

While transactions work for MySQL, PostgreSQL, and SQLite out of the box, MongoDB requires you to set it up as "replica set" first.

To convert a standard MongoDB instance to a replica set, please read the official documentation Convert a Standalone to a Replica Set.

Made in Germany