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

Commit 83be13fa by papb

test(transaction): try to fix flaky postgres test

1 parent fbf3a4cc
Showing with 65 additions and 25 deletions
...@@ -110,39 +110,79 @@ if (current.dialect.supports.transactions) { ...@@ -110,39 +110,79 @@ if (current.dialect.supports.transactions) {
expect(hook).to.not.have.been.called; expect(hook).to.not.have.been.called;
}); });
//Promise rejection test is specific to postgres
if (dialect === 'postgres') { if (dialect === 'postgres') {
it('do not rollback if already committed', async function() { // See #3689, #3726 and #6972 (https://github.com/sequelize/sequelize/pull/6972/files#diff-533eac602d424db379c3d72af5089e9345fd9d3bbe0a26344503c22a0a5764f7L75)
const SumSumSum = this.sequelize.define('transaction', { it('does not try to rollback a transaction that failed upon committing with SERIALIZABLE isolation level (#3689)', async function() {
value: { // See https://wiki.postgresql.org/wiki/SSI
type: Support.Sequelize.DECIMAL(10, 3),
field: 'value' const Dots = this.sequelize.define('dots', { color: Sequelize.STRING });
} await Dots.sync({ force: true });
});
const initialData = [
const transTest = val => { { color: 'red' },
return this.sequelize.transaction({ { color: 'green' },
isolationLevel: Transaction.ISOLATION_LEVELS.SERIALIZABLE { color: 'green' },
}, async t => { { color: 'red' },
await delay(1000); { color: 'green' },
await SumSumSum.sum('value', { transaction: t }); { color: 'red' },
await delay(1000); { color: 'green' },
await SumSumSum.create({ value: -val }, { transaction: t }); { color: 'green' },
await delay(1000); { color: 'green' },
{ color: 'red' },
{ color: 'red' },
{ color: 'red' },
{ color: 'green' },
{ color: 'red' },
{ color: 'red' },
{ color: 'red' },
{ color: 'green' },
{ color: 'red' }
];
await Dots.bulkCreate(initialData);
const isolationLevel = Transaction.ISOLATION_LEVELS.SERIALIZABLE;
let firstTransactionGotNearCommit = false;
let secondTransactionGotNearCommit = false;
const firstTransaction = async () => {
await this.sequelize.transaction({ isolationLevel }, async t => {
await Dots.update({ color: 'red' }, {
where: { color: 'green' },
transaction: t
});
await delay(1500);
firstTransactionGotNearCommit = true;
}); });
}; };
await SumSumSum.sync({ force: true }); const secondTransaction = async () => {
await delay(500);
await this.sequelize.transaction({ isolationLevel }, async t => {
await Dots.update({ color: 'green' }, {
where: { color: 'red' },
transaction: t
});
// Sanity check - in this test we want this line to be reached before the
// first transaction gets to commit
expect(firstTransactionGotNearCommit).to.be.false;
secondTransactionGotNearCommit = true;
});
};
await expect( await expect(
Promise.all([ Promise.all([firstTransaction(), secondTransaction()])
transTest(80),
transTest(80)
])
).to.eventually.be.rejectedWith('could not serialize access due to read/write dependencies among transactions'); ).to.eventually.be.rejectedWith('could not serialize access due to read/write dependencies among transactions');
// one row was created, another was rejected due to rollback expect(firstTransactionGotNearCommit).to.be.true;
expect(await SumSumSum.count()).to.equal(1); expect(secondTransactionGotNearCommit).to.be.true;
// Only the second transaction worked
expect(await Dots.count({ where: { color: 'red' } })).to.equal(0);
expect(await Dots.count({ where: { color: 'green' } })).to.equal(initialData.length);
}); });
} }
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!