Sequelize.js Sequelize并发事务在PostgreSQL中的事务中变为空闲
当我使用Sequelize.js Sequelize并发事务在PostgreSQL中的事务中变为空闲,sequelize.js,Sequelize.js,当我使用sequelize.transaction()创建足够多的并发事务时,sequelize不会进行 例如,如果我在pool.max=5的情况下启动5个事务,sequelize将执行启动事务在postgres中,不执行任何进一步的操作 测试用例是: const { Sequelize } = require('sequelize'); function parseArgs(argv = process.argv) { return argv.slice(argv.findIndex((
sequelize.transaction()
创建足够多的并发事务时,sequelize不会进行
例如,如果我在pool.max=5的情况下启动5个事务,sequelize将执行启动事务代码>在postgres中,不执行任何进一步的操作
测试用例是:
const { Sequelize } = require('sequelize');
function parseArgs(argv = process.argv) {
return argv.slice(argv.findIndex((x) => x === __filename) + 1);
}
const args = parseArgs();
const count = parseInt(args[0]) || 5;
const sequelize = new Sequelize('postgres://postgres@localhost:5432/postgres', {
seederStorage: 'sequelize',
dialect: 'postgres',
define: {
timestamps: false,
},
// logging: false,
pool: {
max: count, // keeping max pool size to equal to concurrent transactions
},
});
async function query() {
await sequelize.transaction(async (transaction) => {
// Just doing any query inside transaction. Using model yields same result.
// If no query is run inside transaction, sequelize progresses fine.
const one = await sequelize.query('SELECT 1');
console.log('Queried one', one);
});
}
async function concurrentQuery({ count = 1 }) {
const promises = [];
for (let i = 0; i < count; i++) {
promises.push(query());
}
console.log('Started promises', { count: promises.length });
await Promise.all(promises);
}
concurrentQuery({ count })
.then(() => {
console.log('result', 'pool config', sequelize.config.pool);
})
.catch((err) => {
console.error(err);
})
.finally(() => {
sequelize.close()
.then(() => {
console.log('Closed sequelize');
})
.catch((err) => {
console.error(err);
});
});
和查询postgres:
postgres@localhost:postgres> SELECT pid, now() - pg_stat_activity.query_start AS duration, query, state FROM pg_stat_activity WHERE (now() - pg_stat_activity.query_start) >
interval '2 seconds';
+-------+----------------+--------------------+---------------------+
| pid | duration | query | state |
|-------+----------------+--------------------+---------------------|
| 1042 | 0:00:22.191851 | START TRANSACTION; | idle in transaction |
| 1043 | 0:00:22.187831 | START TRANSACTION; | idle in transaction |
| 1044 | 0:00:22.188163 | START TRANSACTION; | idle in transaction |
| 1045 | 0:00:22.188316 | START TRANSACTION; | idle in transaction |
| 1046 | 0:00:22.180694 | START TRANSACTION; | idle in transaction |
+-------+----------------+--------------------+---------------------+
SELECT 5
Time: 0.019s
使用Sequelize v5(具有节点12)和v6(具有节点14)进行测试
这是虫子吗?或者,我应该提供足够的pool.max来弥补交通堵塞吗?如果预期并发事务的峰值为200,则将pool.max设置为201,可能会导致postgres过载?数据库事务和池中可用连接的数量与您的问题所示的方式无关。无论您的查询使用的是什么事务,连接池都会工作——它会根据需要将它们移交给您。当您启动事务时,它确保您在事务中所做的更改是原子的,并且不会与来自事务外部的更新冲突。由于您没有将创建的事务传递到后续查询中,它将挂起,等待您提交或回滚事务中的更改。如果使用async/await
,则更易于阅读
异步函数查询(){
//获得交易
const transaction=wait sequelize.transaction();
//将事务传递给查询
wait one=wait sequelize.query('SELECT 1',{transaction});
//等待事务。提交();
console.log('查询一个',一个);
}
谢谢。我完全忽略了这样一个事实,即我需要传递事务
对象。通过传递事务,我不会在postgres中出现“事务中空闲”的行为。
postgres@localhost:postgres> SELECT pid, now() - pg_stat_activity.query_start AS duration, query, state FROM pg_stat_activity WHERE (now() - pg_stat_activity.query_start) >
interval '2 seconds';
+-------+----------------+--------------------+---------------------+
| pid | duration | query | state |
|-------+----------------+--------------------+---------------------|
| 1042 | 0:00:22.191851 | START TRANSACTION; | idle in transaction |
| 1043 | 0:00:22.187831 | START TRANSACTION; | idle in transaction |
| 1044 | 0:00:22.188163 | START TRANSACTION; | idle in transaction |
| 1045 | 0:00:22.188316 | START TRANSACTION; | idle in transaction |
| 1046 | 0:00:22.180694 | START TRANSACTION; | idle in transaction |
+-------+----------------+--------------------+---------------------+
SELECT 5
Time: 0.019s