Add index on (user_id, shown) in notification table to optimize markNotificationsShown queries and prevent deadlocks. Implement transaction handling in markNotificationsShown method for atomic updates.
This commit is contained in:
@@ -0,0 +1,30 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
async up(queryInterface, Sequelize) {
|
||||||
|
// Create index on (user_id, shown) to optimize markNotificationsShown queries
|
||||||
|
// This prevents deadlocks by allowing fast lookups and reducing lock contention
|
||||||
|
await queryInterface.sequelize.query(`
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1 FROM pg_class c
|
||||||
|
JOIN pg_namespace n ON n.oid = c.relnamespace
|
||||||
|
WHERE c.relkind = 'i'
|
||||||
|
AND c.relname = 'idx_notification_user_id_shown'
|
||||||
|
AND n.nspname = 'falukant_log'
|
||||||
|
) THEN
|
||||||
|
CREATE INDEX idx_notification_user_id_shown
|
||||||
|
ON falukant_log.notification (user_id, shown);
|
||||||
|
END IF;
|
||||||
|
END$$;
|
||||||
|
`);
|
||||||
|
},
|
||||||
|
|
||||||
|
async down(queryInterface, Sequelize) {
|
||||||
|
await queryInterface.sequelize.query(`
|
||||||
|
DROP INDEX IF EXISTS falukant_log.idx_notification_user_id_shown;
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
@@ -4382,11 +4382,26 @@ class FalukantService extends BaseService {
|
|||||||
|
|
||||||
async markNotificationsShown(hashedUserId) {
|
async markNotificationsShown(hashedUserId) {
|
||||||
const user = await getFalukantUserOrFail(hashedUserId);
|
const user = await getFalukantUserOrFail(hashedUserId);
|
||||||
const [count] = await Notification.update(
|
|
||||||
{ shown: true },
|
// Use transaction to prevent deadlocks and ensure atomicity
|
||||||
{ where: { userId: user.id, shown: false } }
|
const transaction = await sequelize.transaction({
|
||||||
);
|
isolationLevel: Sequelize.Transaction.ISOLATION_LEVELS.READ_COMMITTED
|
||||||
return { updated: count };
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const [count] = await Notification.update(
|
||||||
|
{ shown: true },
|
||||||
|
{
|
||||||
|
where: { userId: user.id, shown: false },
|
||||||
|
transaction
|
||||||
|
}
|
||||||
|
);
|
||||||
|
await transaction.commit();
|
||||||
|
return { updated: count };
|
||||||
|
} catch (error) {
|
||||||
|
await transaction.rollback();
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getPoliticalOfficeHolders(hashedUserId) {
|
async getPoliticalOfficeHolders(hashedUserId) {
|
||||||
|
|||||||
Reference in New Issue
Block a user