Skip to content

Commit

Permalink
set transaction isolation level (#38)
Browse files Browse the repository at this point in the history
* set transsaction isolation level

* 2.5.6
  • Loading branch information
kbarbounakis authored Oct 10, 2023
1 parent f51b1a9 commit 9c699dc
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 12 deletions.
20 changes: 19 additions & 1 deletion MSSqlAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const util = require('util');
const { TraceUtils } = require('@themost/common');
const { QueryExpression, SqlUtils } = require('@themost/query');
const { MSSqlFormatter } = require('./MSSqlFormatter');
const { TransactionIsolationLevelFormatter } = require('./TransactionIsolationLevel')
/**
* @class
*/
Expand Down Expand Up @@ -64,6 +65,14 @@ class MSSqlAdapter {
let callbackAlreadyCalled = false;
// clone connection options
const connectionOptions = Object.assign({}, self.options);

let transactionIsolationLevel = null;
if (connectionOptions && connectionOptions.options) {
if (Object.prototype.hasOwnProperty.call(connectionOptions.options, 'transactionIsolationLevel')) {
const level = connectionOptions.options.transactionIsolationLevel;
transactionIsolationLevel = new TransactionIsolationLevelFormatter().format(level);
}
}
// create connection
self.rawConnection = new mssql.Connection(connectionOptions);
self.rawConnection.on('error', function(err) {
Expand All @@ -77,8 +86,17 @@ class MSSqlAdapter {
if (err) {
self.rawConnection = null;
TraceUtils.log(err);
return callback(err);
}
return callback(err);
if (transactionIsolationLevel == null) {
return callback();
}
return self.execute(transactionIsolationLevel, [], function(err) {
if (err) {
return callback(err);
}
return callback();
});
});
}
/**
Expand Down
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,42 @@ Register MSSQL adapter on app.json as follows:

If you are intended to use MSSQL data adapter as the default database adapter set the property "default" to true.

### Transaction Isolation Level

Transaction isolation level controls the locking and row versioning behavior of Transact-SQL statements issued by a connection to SQL Server.

```sql
SET TRANSACTION ISOLATION LEVEL
{ READ UNCOMMITTED
| READ COMMITTED
| REPEATABLE READ
| SNAPSHOT
| SERIALIZABLE
}
```

[https://learn.microsoft.com/en-us/sql/t-sql/statements/set-transaction-isolation-level-transact-sql?view=sql-server-ver16](https://learn.microsoft.com/en-us/sql/t-sql/statements/set-transaction-isolation-level-transact-sql?view=sql-server-ver16)

Use `options/transactionIsolationLevel` and define transaction isolation level:

```json
{
"name":"development",
"invariantName":"mssql",
"default":true,
"options": {
"server":"localhost",
"user":"user",
"password":"password",
"database":"test",
"options": {
"transactionIsolationLevel": "readCommitted"
}
}
}
```
The possible values are `readUncommitted` | `readCommitted` | `repeatableRead` | `snapshot` | `serializable`

## Development
`themost-mssql` is a sub-module of [ Most Web Framework data adapters project](https://github.com/themost-framework/themost-adapters)

Expand Down
33 changes: 33 additions & 0 deletions TransactionIsolationLevel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

const TransactionIsolationLevelEnum = {
readUncommitted: 'READ UNCOMMITTED',
readCommitted: 'READ COMMITTED',
repeatableRead: 'REPEATABLE READ',
snapshot: 'SNAPSHOT',
serializable: 'SERIALIZABLE'
}

Object.freeze(TransactionIsolationLevelEnum);

class TransactionIsolationLevelFormatter {

/**
* @param {'readUncommitted' | 'readCommitted' | 'repeatableRead' | 'snapshot' | 'serializable'} isolationLevel
* @returns {string}
*/
format(isolationLevel) {
if (Object.prototype.hasOwnProperty.call(TransactionIsolationLevelEnum, isolationLevel)) {
let sql = 'SET TRANSACTION ISOLATION LEVEL';
sql += ' ';
sql += TransactionIsolationLevelEnum[isolationLevel];
return sql;
}
throw new TypeError('The specified transaction isolation level is invalid');
}

}

module.exports = {
TransactionIsolationLevelEnum,
TransactionIsolationLevelFormatter
}
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,6 +1,6 @@
{
"name": "@themost/mssql",
"version": "2.5.5",
"version": "2.5.6",
"description": "MOST Web Framework MSSQL Data Adapter",
"main": "index.js",
"scripts": {
Expand Down
21 changes: 12 additions & 9 deletions spec/MSSqlAdapter.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,22 @@ const ProductModel = require('./config/models/Product.json');
const EmployeeModel = require('./config/models/Employee.json');
// get options from environmet for testing
const testConnectionOptions = {
"server": process.env.MSSQL_SERVER,
"port": process.env.MSSQL_SERVER_PORT,
"user": process.env.MSSQL_USER,
"password": process.env.MSSQL_PASSWORD,
"database": "test_themost_dev"
"server": process.env.DB_HOST,
"port": process.env.DB_PORT,
"user": process.env.DB_USER,
"password": process.env.DB_PASSWORD,
"database": "test_themost_dev",
"options": {
"transactionIsolationLevel": "readCommitted"
}
};

// get options from environmet for testing
const masterConnectionOptions = {
"server": process.env.MSSQL_SERVER,
"port": process.env.MSSQL_SERVER_PORT,
"user": process.env.MSSQL_USER,
"password": process.env.MSSQL_PASSWORD,
"server": process.env.DB_HOST,
"port": process.env.DB_PORT,
"user": process.env.DB_USER,
"password": process.env.DB_PASSWORD,
"database": "master"
};

Expand Down

0 comments on commit 9c699dc

Please sign in to comment.