Created
November 29, 2021 12:20
-
-
Save GoodnessEzeokafor/29f0cac84c6b1f32c0c7f053388e0762 to your computer and use it in GitHub Desktop.
Mongo-Db-Transactions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Rules for MONGODB Multi Document Transactions | |
* All data modeling rules still applies | |
* Transactions should be the most common operation | |
* Pass in the session to all statements | |
* Implement retry logic , transactions can always abort | |
* Plan for DDL operations | |
*/ | |
import db, { ClientSession } from 'mongoose'; | |
/** | |
* Source: https://docs.mongodb.com/manual/reference/method/Session.commitTransaction/ | |
*/ | |
const databaseHelper = { | |
runTransactionWithRetry: async (txnFunc: any, session: ClientSession) => { | |
let retries = 0 | |
while (retries < 3) { | |
try { | |
console.log("-------- runTransactionWithRetry function ----------") | |
await txnFunc(session); // performs transaction | |
await session.commitTransaction(); // Uses write concern set at transaction start. | |
console.log("-------- runTransactionWithRetry function ----------") | |
console.log("Transaction commited.............") | |
// commit transaction | |
break; | |
} catch (error: any) { | |
// If transient error, retry the whole transaction | |
console.log("----------------error during commit ------------------") | |
console.log(error) | |
console.log("----------------error during commit ------------------") | |
console.log(error.errorLabels) | |
if (error.hasOwnProperty("errorLabels") && error.errorLabels.includes("TransientTransactionError")) { | |
console.log("TransientTransactionError, retrying transaction ..."); | |
retries++ | |
continue; | |
} else if (error.hasOwnProperty("errorLabels") && error.errorLabels.includes("UnknownTransactionCommitResult")) { | |
console.log("UnknownTransactionCommitResult, retrying commit operation ..."); | |
retries++ | |
continue; | |
} else { | |
await session.abortTransaction(); | |
return Promise.reject(error); | |
} | |
} | |
} | |
}, | |
commitWithRetry: async (session: ClientSession) => { | |
while (true) { | |
try { | |
session.commitTransaction(); // Uses write concern set at transaction start. | |
console.log("Transaction committed."); | |
break; | |
} catch (error: any) { | |
// Can retry commit | |
if (error.hasOwnProperty("errorLabels") && error.errorLabels.includes("UnknownTransactionCommitResult")) { | |
console.log("UnknownTransactionCommitResult, retrying commit operation ..."); | |
continue; | |
} else { | |
console.log("Error during commit ..."); | |
throw error; | |
} | |
} | |
} | |
}, | |
executeTransaction: async (transactionProcess: any) => { | |
const session = await db.startSession(); | |
session.startTransaction(); | |
try { | |
await databaseHelper.runTransactionWithRetry(transactionProcess, session); | |
} catch (error: any) { | |
return Promise.reject(error) ; | |
} finally { | |
await session.endSession(); | |
} | |
} | |
} | |
export default databaseHelper | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment