Skip to content

Commit

Permalink
feat: changed to use transaction instead of managing sessions manuall…
Browse files Browse the repository at this point in the history
…y. And only when a transaction is needed (#14)

* feat: changed to use transaction only when needed

* fix: prevent creating another transaction if there is one active

* refactor: improve readability
  • Loading branch information
javierdelafuentesales authored Feb 21, 2024
1 parent 911cf6c commit d50246d
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 33 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@streamyard/typeorm",
"private": true,
"version": "0.3.16-4",
"version": "0.3.16-5-beta",
"description": "Data-Mapper ORM for TypeScript, ES7, ES6, ES5. Supports MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, MongoDB, Spanner databases.",
"license": "MIT",
"readmeFilename": "README.md",
Expand Down
59 changes: 28 additions & 31 deletions src/driver/spanner/SpannerQueryRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,9 @@ export class SpannerQueryRunner extends BaseQueryRunner implements QueryRunner {
driver: SpannerDriver

/**
* Real database connection from a connection pool used to perform queries.
* Transaction currently executed.
*/
protected session?: any

/**
* Transaction currently executed by this session.
*/
protected sessionTransaction?: any
protected currentTransaction?: any

// -------------------------------------------------------------------------
// Constructor
Expand All @@ -69,14 +64,16 @@ export class SpannerQueryRunner extends BaseQueryRunner implements QueryRunner {
* Returns obtained database connection.
*/
async connect(): Promise<any> {
if (this.session) {
return Promise.resolve(this.session)
}
return Promise.resolve(this.driver.instanceDatabase)
}

protected async initTransaction() {
if (this.currentTransaction) return this.currentTransaction

const [session] = await this.driver.instanceDatabase.createSession({})
this.session = session
this.sessionTransaction = await session.transaction()
return this.session
const [transaction] =
await this.driver.instanceDatabase.getTransaction()
this.currentTransaction = transaction
return this.currentTransaction
}

/**
Expand All @@ -85,10 +82,10 @@ export class SpannerQueryRunner extends BaseQueryRunner implements QueryRunner {
*/
async release(): Promise<void> {
this.isReleased = true
if (this.session) {
await this.session.delete()
if (this.currentTransaction) {
await this.currentTransaction.end()
}
this.session = undefined
this.currentTransaction = undefined
return Promise.resolve()
}

Expand All @@ -104,8 +101,8 @@ export class SpannerQueryRunner extends BaseQueryRunner implements QueryRunner {
throw err
}

await this.connect()
await this.sessionTransaction.begin()
await this.initTransaction()
await this.currentTransaction.begin()
this.connection.logger.logQuery("START TRANSACTION")

await this.broadcaster.broadcast("AfterTransactionStart")
Expand All @@ -116,12 +113,12 @@ export class SpannerQueryRunner extends BaseQueryRunner implements QueryRunner {
* Error will be thrown if transaction was not started.
*/
async commitTransaction(): Promise<void> {
if (!this.isTransactionActive || !this.sessionTransaction)
if (!this.isTransactionActive || !this.currentTransaction)
throw new TransactionNotStartedError()

await this.broadcaster.broadcast("BeforeTransactionCommit")

await this.sessionTransaction.commit()
await this.currentTransaction.commit()
this.connection.logger.logQuery("COMMIT")
this.isTransactionActive = false

Expand All @@ -133,12 +130,12 @@ export class SpannerQueryRunner extends BaseQueryRunner implements QueryRunner {
* Error will be thrown if transaction was not started.
*/
async rollbackTransaction(): Promise<void> {
if (!this.isTransactionActive || !this.sessionTransaction)
if (!this.isTransactionActive || !this.currentTransaction)
throw new TransactionNotStartedError()

await this.broadcaster.broadcast("BeforeTransactionRollback")

await this.sessionTransaction.rollback()
await this.currentTransaction.rollback()
this.connection.logger.logQuery("ROLLBACK")
this.isTransactionActive = false

Expand All @@ -157,7 +154,6 @@ export class SpannerQueryRunner extends BaseQueryRunner implements QueryRunner {

try {
const queryStartTime = +new Date()
await this.connect()
let rawResult:
| [
any[],
Expand All @@ -171,14 +167,15 @@ export class SpannerQueryRunner extends BaseQueryRunner implements QueryRunner {
]
| undefined = undefined
const isSelect = query.startsWith("SELECT")
if (!this.isTransactionActive && !isSelect) {
await this.initTransaction()
await this.currentTransaction.begin()
}

const executor =
isSelect && !this.isTransactionActive
? this.driver.instanceDatabase
: this.sessionTransaction

if (!this.isTransactionActive && !isSelect) {
await this.sessionTransaction.begin()
}
: this.currentTransaction

try {
this.driver.connection.logger.logQuery(query, parameters, this)
Expand All @@ -193,13 +190,13 @@ export class SpannerQueryRunner extends BaseQueryRunner implements QueryRunner {
json: true,
})
if (!this.isTransactionActive && !isSelect) {
await this.sessionTransaction.commit()
await this.currentTransaction.commit()
}
} catch (error) {
try {
// we throw original error even if rollback thrown an error
if (!this.isTransactionActive && !isSelect)
await this.sessionTransaction.rollback()
await this.currentTransaction.rollback()
} catch (rollbackError) {}
throw error
}
Expand Down

0 comments on commit d50246d

Please sign in to comment.