Concurrent nested transactions are not compatible with connection pool of finite size
See original GitHub issueWhat are you doing?
When using connection pool with maximum number of connections then there should not be “dependencies” between connections or else deadlock can happen. I suppose concurrent nested transactions is feature of sequelize as they are mentioned in documentation: http://docs.sequelizejs.com/manual/transactions.html#concurrent-partial-transactions
I borrowed example from documentation, deleted some lines and created function nested
from it:
let Sequelize = require("sequelize");
let sequelize = new Sequelize({ dialect: "mysql" });
let nested = function()
{
return sequelize.transaction((t1) => {
return sequelize.transaction((t2) => {
});
});
};
Promise.all([nested(), nested(), nested(), nested(), nested()]).then(() => console.log("done"));
Output can be similar to this:
22:29:24.751 - Executing (52c933c4-50dc-49e8-8d34-11e1e916e920): START TRANSACTION;
22:29:24.758 - Executing (0009969f-e4a0-4a1e-ad55-967bb3beea44): START TRANSACTION;
22:29:24.760 - Executing (5729d881-fa7c-4bb0-b02f-d1618740bc34): START TRANSACTION;
22:29:24.762 - Executing (9060a023-455b-49f7-bcbb-2ccefe9b6685): START TRANSACTION;
22:29:24.763 - Executing (0fd8646b-e298-4989-922e-16d546897d6f): START TRANSACTION;
22:30:24.762 - Executing (52c933c4-50dc-49e8-8d34-11e1e916e920): ROLLBACK;
22:30:24.765 - Executing (17dad8f9-0cde-406d-8bb6-51a21b1c17dd): START TRANSACTION;
Unhandled rejection SequelizeConnectionAcquireTimeoutError: Operation timeout
at pool.acquire.catch.err
at tryCatcher
...
22:30:24.771 - Executing (17dad8f9-0cde-406d-8bb6-51a21b1c17dd): COMMIT;
22:30:24.775 - Executing (5729d881-fa7c-4bb0-b02f-d1618740bc34): ROLLBACK;
22:30:24.777 - Executing (9060a023-455b-49f7-bcbb-2ccefe9b6685): ROLLBACK;
22:30:24.778 - Executing (0fd8646b-e298-4989-922e-16d546897d6f): ROLLBACK;
22:30:24.782 - Executing (0009969f-e4a0-4a1e-ad55-967bb3beea44): COMMIT;
Naive solution would be to increase maximum number of connections but none finite value will work well in theory when number of concurrent requests/calls to function nested
is also not limited so the best solution would be to not limit number of connections in pool or to not use concurrent nested transactions. But then is lost benefit of having limited number of db connections. Sequelize should see these types of dependencies and maybe is possible to avoid such deadlocks. Maybe multiple pools could help one for each nesting and option in seuqelize config for (maximum) number of pools or create new pools automatically to avoid deadlocks (or resize pool temporarily above max number of connections in case of deadlock).
To Reproduce Steps to reproduce the behavior:
- Setup sequelize with maximum number of connections in pool set to 5 (default as of writing this)
- Run example code
- See error
What do you expect to happen?
To not see deadlock and this error.
What is actually happening?
Deadlock and sequelize error.
Environment
Dialect:
- mysql
- postgres
- sqlite
- mssql
- any Sequelize version: 5.8.6
Issue Analytics
- State:
- Created 4 years ago
- Reactions:1
- Comments:7 (4 by maintainers)
You mean to remove that comment about CLS? Ok done.
Result is exactly same whether I setup sequelize with or without CLS.
I just copied part of example from sequelize documentation with headings “Concurrent/Partial transactions” and “Without CLS enabled”.
The bot will remove the stale label when it runs again tonight. There is work being done that you don’t have to ping every one of your issues every 14 days. That is part of #13648