mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
transaction handling fixes
This commit is contained in:
parent
0df7851214
commit
e0b4b369dc
@ -47,7 +47,7 @@ async function copyFile(backupFile) {
|
|||||||
|
|
||||||
for (; attemptCount < COPY_ATTEMPT_COUNT && !success; attemptCount++) {
|
for (; attemptCount < COPY_ATTEMPT_COUNT && !success; attemptCount++) {
|
||||||
try {
|
try {
|
||||||
await sql.executeNoWrap(`VACUUM INTO '${backupFile}'`);
|
await sql.executeWithoutTransaction(`VACUUM INTO '${backupFile}'`);
|
||||||
|
|
||||||
success = true;
|
success = true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -140,10 +140,6 @@ async function updateEntity(entity) {
|
|||||||
await eventService.emit(entity.isDeleted ? eventService.ENTITY_DELETED : eventService.ENTITY_CHANGED, eventPayload);
|
await eventService.emit(entity.isDeleted ? eventService.ENTITY_DELETED : eventService.ENTITY_CHANGED, eventPayload);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity.afterSaving) {
|
|
||||||
await entity.afterSaving();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,4 +155,4 @@ module.exports = {
|
|||||||
getOption,
|
getOption,
|
||||||
updateEntity,
|
updateEntity,
|
||||||
setEntityConstructor
|
setEntityConstructor
|
||||||
};
|
};
|
||||||
|
@ -155,7 +155,7 @@ async function execute(query, params = []) {
|
|||||||
return await wrap(async db => db.run(query, ...params), query);
|
return await wrap(async db => db.run(query, ...params), query);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function executeNoWrap(query, params = []) {
|
async function executeWithoutTransaction(query, params = []) {
|
||||||
await dbConnection.run(query, ...params);
|
await dbConnection.run(query, ...params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,10 +222,12 @@ async function startTransactionIfNecessary() {
|
|||||||
await transactionPromise;
|
await transactionPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
await beginTransaction();
|
// first set semaphore (atomic operation and only then start transaction
|
||||||
cls.namespace.set('isInTransaction', true);
|
|
||||||
transactionActive = true;
|
transactionActive = true;
|
||||||
transactionPromise = new Promise(res => transactionPromiseResolve = res);
|
transactionPromise = new Promise(res => transactionPromiseResolve = res);
|
||||||
|
cls.namespace.set('isInTransaction', true);
|
||||||
|
|
||||||
|
await beginTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function transactional(func) {
|
async function transactional(func) {
|
||||||
@ -234,7 +236,7 @@ async function transactional(func) {
|
|||||||
return await func();
|
return await func();
|
||||||
}
|
}
|
||||||
|
|
||||||
cls.namespace.set('isTransactional', true); // we will need a transaction if there's a write operation
|
cls.namespace.set('isTransactional', true); // this signals that transaction will be needed if there's a write operation
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const ret = await func();
|
const ret = await func();
|
||||||
@ -244,26 +246,27 @@ async function transactional(func) {
|
|||||||
|
|
||||||
// note that sync rows sent from this action will be sent again by scheduled periodic ping
|
// note that sync rows sent from this action will be sent again by scheduled periodic ping
|
||||||
require('./ws.js').sendPingToAllClients();
|
require('./ws.js').sendPingToAllClients();
|
||||||
|
|
||||||
transactionActive = false;
|
|
||||||
cls.namespace.set('isInTransaction', false);
|
|
||||||
transactionPromiseResolve();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
if (transactionActive) {
|
if (cls.namespace.get('isInTransaction')) {
|
||||||
await rollback();
|
await rollback();
|
||||||
|
|
||||||
transactionActive = false;
|
|
||||||
cls.namespace.set('isInTransaction', false);
|
|
||||||
// resolving since this is just semaphore for allowing another write transaction to proceed
|
|
||||||
transactionPromiseResolve();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
|
cls.namespace.set('isTransactional', false);
|
||||||
|
|
||||||
|
if (cls.namespace.get('isInTransaction')) {
|
||||||
|
transactionActive = false;
|
||||||
|
cls.namespace.set('isInTransaction', false);
|
||||||
|
// resolving even for rollback since this is just semaphore for allowing another write transaction to proceed
|
||||||
|
transactionPromiseResolve();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
@ -278,7 +281,7 @@ module.exports = {
|
|||||||
getMap,
|
getMap,
|
||||||
getColumn,
|
getColumn,
|
||||||
execute,
|
execute,
|
||||||
executeNoWrap,
|
executeWithoutTransaction,
|
||||||
executeMany,
|
executeMany,
|
||||||
executeScript,
|
executeScript,
|
||||||
transactional,
|
transactional,
|
||||||
|
@ -372,7 +372,7 @@ sqlInit.dbReady.then(async () => {
|
|||||||
setInterval(cls.wrap(sync), 60000);
|
setInterval(cls.wrap(sync), 60000);
|
||||||
|
|
||||||
// kickoff initial sync immediately
|
// kickoff initial sync immediately
|
||||||
setTimeout(cls.wrap(sync), 1000);
|
setTimeout(cls.wrap(sync), 3000);
|
||||||
|
|
||||||
setInterval(cls.wrap(updatePushStats), 1000);
|
setInterval(cls.wrap(updatePushStats), 1000);
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user