added dirty read(NOLOCK) in SQLServer

This commit is contained in:
Alfonso Alonso Lorenzo 2019-05-13 13:29:55 +02:00
parent 79110d93cf
commit b571f5dd69
5 changed files with 54 additions and 4 deletions

View File

@ -120,7 +120,7 @@ userRepository.find({
```
or
```ts
{ mode: "pessimistic_read"|"pessimistic_write" }
{ mode: "pessimistic_read"|"pessimistic_write"|"dirty_read" }
```
for example:

View File

@ -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

View File

@ -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.

View File

@ -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;
@ -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;
}
}
@ -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();
}

View File

@ -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;
@ -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")