diff --git a/adonis-typings/database.ts b/adonis-typings/database.ts index 5f7446fb..5aaadd4b 100644 --- a/adonis-typings/database.ts +++ b/adonis-typings/database.ts @@ -34,6 +34,17 @@ declare module '@ioc:Adonis/Lucid/Database' { export { SimplePaginatorContract, SimplePaginatorMetaKeys } + /** + * Same as knex. Need to redefine, as knex doesn't export this + * type + */ + export type IsolationLevels = + | 'read uncommitted' + | 'read committed' + | 'snapshot' + | 'repeatable read' + | 'serializable' + /** * Migration node returned by the migration source * implementation @@ -64,8 +75,11 @@ declare module '@ioc:Adonis/Lucid/Database' { * Shape of the transaction function to create a new transaction */ export interface TransactionFn { - (callback: (trx: TransactionClientContract) => Promise): Promise - (): Promise + ( + callback: (trx: TransactionClientContract) => Promise, + options?: { isolationLevel?: IsolationLevels } + ): Promise + (options?: { isolationLevel?: IsolationLevels }): Promise } /** diff --git a/src/Database/index.ts b/src/Database/index.ts index 1b4ed33b..8c8897db 100644 --- a/src/Database/index.ts +++ b/src/Database/index.ts @@ -20,6 +20,8 @@ import { DatabaseClientOptions, TransactionClientContract, ConnectionManagerContract, + IsolationLevels, + QueryClientContract, } from '@ioc:Adonis/Lucid/Database' import { QueryClient } from '../QueryClient' @@ -123,7 +125,7 @@ export class Database implements DatabaseContract { public connection( connection: string = this.primaryConnectionName, options?: DatabaseClientOptions - ) { + ): QueryClientContract | TransactionClientContract { options = options || {} /** @@ -256,8 +258,16 @@ export class Database implements DatabaseContract { * Returns a transaction instance on the default * connection */ - public transaction(callback?: (trx: TransactionClientContract) => Promise) { - return this.connection().transaction(callback) + public transaction( + callback?: + | { isolationLevel?: IsolationLevels } + | ((trx: TransactionClientContract) => Promise), + options?: { isolationLevel?: IsolationLevels } + ) { + const client = this.connection() + return typeof callback === 'function' + ? client.transaction(callback, options) + : client.transaction(callback) } /** diff --git a/src/QueryClient/index.ts b/src/QueryClient/index.ts index 959c2457..329dc4df 100644 --- a/src/QueryClient/index.ts +++ b/src/QueryClient/index.ts @@ -15,6 +15,7 @@ import { EmitterContract } from '@ioc:Adonis/Core/Event' import { ProfilerRowContract, ProfilerContract } from '@ioc:Adonis/Core/Profiler' import { + IsolationLevels, DialectContract, ConnectionContract, QueryClientContract, @@ -130,9 +131,12 @@ export class QueryClient implements QueryClientContract { * query and hold a single connection for all queries. */ public async transaction( - callback?: (trx: TransactionClientContract) => Promise + callback?: + | { isolationLevel?: IsolationLevels } + | ((trx: TransactionClientContract) => Promise), + options?: { isolationLevel?: IsolationLevels } ): Promise { - const trx = await this.getWriteClient().transaction() + const trx = await this.getWriteClient().transaction(options) const transaction = new TransactionClient( trx, this.dialect, diff --git a/src/TransactionClient/index.ts b/src/TransactionClient/index.ts index 1fd19b0a..ed7e19f7 100644 --- a/src/TransactionClient/index.ts +++ b/src/TransactionClient/index.ts @@ -13,7 +13,11 @@ import { Knex } from 'knex' import { EventEmitter } from 'events' import { EmitterContract } from '@ioc:Adonis/Core/Event' import { ProfilerRowContract } from '@ioc:Adonis/Core/Profiler' -import { TransactionClientContract, DialectContract } from '@ioc:Adonis/Lucid/Database' +import { + IsolationLevels, + DialectContract, + TransactionClientContract, +} from '@ioc:Adonis/Lucid/Database' import { ModelQueryBuilder } from '../Orm/QueryBuilder' import { RawBuilder } from '../Database/StaticBuilder/Raw' @@ -180,9 +184,12 @@ export class TransactionClient extends EventEmitter implements TransactionClient * Returns another instance of transaction with save point */ public async transaction( - callback?: (trx: TransactionClientContract) => Promise + callback?: + | { isolationLevel?: IsolationLevels } + | ((trx: TransactionClientContract) => Promise), + options?: { isolationLevel?: IsolationLevels } ): Promise { - const trx = await this.knexClient.transaction() + const trx = await this.knexClient.transaction(options) const transaction = new TransactionClient( trx, this.dialect,