Skip to content

Commit

Permalink
added dirty read(NOLOCK) in SQLServer
Browse files Browse the repository at this point in the history
  • Loading branch information
Alfonso Alonso Lorenzo committed May 13, 2019
1 parent 79110d9 commit b571f5d
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 4 deletions.
2 changes: 1 addition & 1 deletion docs/find-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ userRepository.find({
```
or
```ts
{ mode: "pessimistic_read"|"pessimistic_write" }
{ mode: "pessimistic_read"|"pessimistic_write"|"dirty_read" }
```

for example:
Expand Down
8 changes: 8 additions & 0 deletions docs/select-query-builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,14 @@ const users = await getRepository(User)
.getMany();
```

To use dirty read locking use the following method:

```typescript
const users = await getRepository(User)
.createQueryBuilder("user")
.setLock("dirty_read")
.getMany();
To use optimistic locking use the following method:
```typescript
Expand Down
2 changes: 1 addition & 1 deletion src/query-builder/QueryExpressionMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ export class QueryExpressionMap {
/**
* Locking mode.
*/
lockMode?: "optimistic"|"pessimistic_read"|"pessimistic_write";
lockMode?: "optimistic"|"pessimistic_read"|"pessimistic_write"|"dirty_read";

/**
* Current version of the entity, used for locking.
Expand Down
17 changes: 15 additions & 2 deletions src/query-builder/SelectQueryBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -949,12 +949,12 @@ export class SelectQueryBuilder<Entity> extends QueryBuilder<Entity> implements
/**
* Sets locking mode.
*/
setLock(lockMode: "pessimistic_read"|"pessimistic_write"): this;
setLock(lockMode: "pessimistic_read"|"pessimistic_write"|"dirty_read"): this;

/**
* Sets locking mode.
*/
setLock(lockMode: "optimistic"|"pessimistic_read"|"pessimistic_write", lockVersion?: number|Date): this {
setLock(lockMode: "optimistic"|"pessimistic_read"|"pessimistic_write"|"dirty_read", lockVersion?: number|Date): this {
this.expressionMap.lockMode = lockMode;
this.expressionMap.lockVersion = lockVersion;
return this;
Expand Down Expand Up @@ -1385,6 +1385,9 @@ export class SelectQueryBuilder<Entity> extends QueryBuilder<Entity> implements
case "pessimistic_write":
lock = " WITH (UPDLOCK, ROWLOCK)";
break;
case "dirty_read":
lock = " WITH (NOLOCK)";
break;
}
}

Expand Down Expand Up @@ -1616,6 +1619,16 @@ export class SelectQueryBuilder<Entity> extends QueryBuilder<Entity> implements
} else if (driver instanceof SqlServerDriver) {
return "";

} else {
throw new LockNotSupportedOnGivenDriverError();
}
case "dirty_read":
if (driver instanceof SqlServerDriver) {
return " WITH (NOLOCK)";

} else if (driver instanceof MysqlDriver || driver instanceof PostgresDriver || driver instanceof OracleDriver) {
return "";

} else {
throw new LockNotSupportedOnGivenDriverError();
}
Expand Down
29 changes: 29 additions & 0 deletions test/functional/query-builder/locking/query-builder-locking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,21 @@ describe("query builder > locking", () => {
}
})));

it("should attach dirty read lock statement on query if locking enabled", () => Promise.all(connections.map(async connection => {
if (connection.driver instanceof AbstractSqliteDriver || connection.driver instanceof CockroachDriver)
return;

const sql = connection.createQueryBuilder(PostWithVersion, "post")
.setLock("dirty_read")
.where("post.id = :id", { id: 1 })
.getSql();

if (connection.driver instanceof SqlServerDriver) {
expect(sql.indexOf("WITH (NOLOCK)") !== -1).to.be.true;

}
})));

it("should not attach pessimistic write lock statement on query if locking is not used", () => Promise.all(connections.map(async connection => {
if (connection.driver instanceof AbstractSqliteDriver)
return;
Expand Down Expand Up @@ -129,6 +144,20 @@ describe("query builder > locking", () => {

})));

it("should attach pessimistic read lock statement on query if locking enabled", () => Promise.all(connections.map(async connection => {
if (connection.driver instanceof AbstractSqliteDriver || connection.driver instanceof CockroachDriver)
return;

const sql = connection.createQueryBuilder(PostWithVersion, "post")
.setLock("dirty_read")
.where("post.id = :id", { id: 1 })
.getSql();

if (connection.driver instanceof SqlServerDriver) {
expect(sql.indexOf("WITH (NOLOCK)") !== -1).to.be.true;
}
})));

it("should throw error if optimistic lock used with getMany method", () => Promise.all(connections.map(async connection => {

return connection.createQueryBuilder(PostWithVersion, "post")
Expand Down

0 comments on commit b571f5d

Please sign in to comment.