不要怂,就是干,撸起袖子干!

Commit 7b163084 by joshuacullen Committed by Sushant

feat(postgres): skip locked support (#9197)

1 parent 2752bf7a
......@@ -261,5 +261,26 @@ model.afterSave((instance, options) => {
}
// Save done outside a transaction, safe for callers to fetch the updated model
// Notify
## Locks
Queries within a `transaction` can be performed with locks
```
return User.findAll({
limit: 1,
lock: true,
transaction: t1
})
```
Queries within a transaction can skip locked rows
```
return User.findAll({
limit: 1,
lock: true,
skipLocked: true,
transaction: t2
})
```
......@@ -1327,6 +1327,9 @@ class QueryGenerator {
if (this._dialect.supports.lockOf && options.lock.of && options.lock.of.prototype instanceof Model) {
query += ' OF ' + this.quoteTable(options.lock.of.name);
}
if (this._dialect.supports.skipLocked && options.skipLocked) {
query += ' SKIP LOCKED';
}
}
return `${query};`;
......
......@@ -33,6 +33,7 @@ PostgresDialect.prototype.supports = _.merge(_.cloneDeep(AbstractDialect.prototy
lockOf: true,
lockKey: true,
lockOuterJoinFailure: true,
skipLocked: true,
forShare: 'FOR SHARE',
index: {
concurrently: true,
......
......@@ -290,6 +290,19 @@ class Transaction {
* ```
* UserModel will be locked but TaskModel won't!
*
* You can also skip locked rows:
*
*```js
* t1 // is a transaction
* Model.findAll({
* where: ...,
* transaction: t1,
* lock: true,
* skipLocked: true
* });
* ```
* The query will now return any rows that aren't locked by another transaction
*
* @return {Object}
* @property UPDATE
* @property SHARE
......
......@@ -528,6 +528,50 @@ if (current.dialect.supports.transactions) {
});
});
if (current.dialect.supports.skipLocked) {
it('supports for update with skip locked', function() {
const User = this.sequelize.define('user', {
username: Support.Sequelize.STRING,
awesome: Support.Sequelize.BOOLEAN
});
return this.sequelize.sync({ force: true }).then(() => {
return Promise.all([
User.create(
{ username: 'jan'}
),
User.create(
{ username: 'joe'}
)
]);
}).then(() => {
return this.sequelize.transaction().then(t1 => {
return User.findAll({
limit: 1,
lock: true,
transaction: t1
}).then(results => {
const firstUserId = results[0].id;
return this.sequelize.transaction().then(t2 => {
return User.findAll({
limit: 1,
lock: true,
skipLocked: true,
transaction: t2
}).then(secondResults => {
expect(secondResults[0].id).to.not.equal(firstUserId);
return Promise.all([
t1.commit(),
t2.commit()
]);
});
});
});
});
});
});
}
it('fail locking with outer joins', function() {
const User = this.sequelize.define('User', { username: Support.Sequelize.STRING }),
Task = this.sequelize.define('Task', { title: Support.Sequelize.STRING, active: Support.Sequelize.BOOLEAN }),
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!