diff --git a/packages/data-service/src/data-service.ts b/packages/data-service/src/data-service.ts index 66318b093b5..8cde083fd7c 100644 --- a/packages/data-service/src/data-service.ts +++ b/packages/data-service/src/data-service.ts @@ -2391,10 +2391,8 @@ class DataServiceImpl extends WithLogContext implements DataService { .sort({ _id: 1 }) .toArray(); - if (session.inTransaction()) { - await session.abortTransaction(); - await session.endSession(); - } + await session.abortTransaction(); + await session.endSession(); const changes = docsToPreview.map((before, idx) => ({ before, @@ -2409,10 +2407,14 @@ class DataServiceImpl extends WithLogContext implements DataService { } catch (err: any) { if (isTransactionAbortError(err)) { // The transaction was aborted while it was still calculating the - // preview. Just return something here rather than erroring. + // preview. Just return something here rather than erroring. No + // reason to abort the transaction or end the session again because + // we only got here because that already happened. return { changes: [] }; } + // The only way this if statement would be true is if aborting the + // transaction and ending the session itself failed above. Unlikely. if (session.inTransaction()) { await session.abortTransaction(); await session.endSession(); @@ -2421,11 +2423,13 @@ class DataServiceImpl extends WithLogContext implements DataService { throw err; } }, - async (session) => { - if (session.inTransaction()) { - await session.abortTransaction(); - await session.endSession(); - } + async () => { + // Rely on the session being killed when we cancel the operation. It can + // take a few seconds before the driver reacts, but the Promise.race() + // against the abort signal should cause the UI to immediately be + // notified that the operation was cancelled. We don't abort the + // transaction or end the session as well because the code we run inside + // session.withTransaction() above would experience race conditions. }, abortSignal );