Bird
Raised Fist0
NestJSframework~10 mins

Transactions in NestJS - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Transactions
Start Transaction
↓
Execute DB Operations
↓
Check for Errors
↓
Commit
↓
End Transaction
This flow shows how a transaction starts, runs database operations, then commits if all is good or rolls back if errors occur.
Execution Sample
NestJS
await this.dataSource.transaction(async manager => {
  await manager.save(user);
  await manager.save(profile);
});
This code runs two save operations inside a transaction that commits if both succeed or rolls back if any fail.
Execution Table
StepActionOperationResultTransaction State
1Start transactionBegin transactionTransaction startedActive
2Save userInsert user recordUser savedActive
3Save profileInsert profile recordProfile savedActive
4No errors detectedCheck operationsAll successfulActive
5Commit transactionCommit changesTransaction committedCommitted
6End transactionClose transactionTransaction endedCommitted
💡 Transaction ends after commit because all operations succeeded
Variable Tracker
VariableStartAfter Step 2After Step 3Final
transactionStateNoneActiveActiveCommitted
userSavedFalseTrueTrueTrue
profileSavedFalseFalseTrueTrue
Key Moments - 2 Insights
Why does the transaction rollback instead of commit if an error happens?
If any operation inside the transaction fails (not shown in this trace), the flow moves to rollback instead of commit to undo all changes, ensuring data stays consistent. See step 4 where errors are checked.
What does 'transactionState' mean in the variable tracker?
'transactionState' shows if the transaction is active, committed, or rolled back. It starts None, becomes Active when transaction begins, and ends Committed if successful (see execution_table steps 1 and 5).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what is the transaction state after saving the user?
ACommitted
BNone
CActive
DRolled back
💡 Hint
Check the 'Transaction State' column at step 2 in the execution_table
At which step does the transaction commit?
AStep 5
BStep 4
CStep 3
DStep 6
💡 Hint
Look for the 'Commit transaction' action in the execution_table
If saving the profile failed, what would happen to the transaction state?
AIt would stay Active
BIt would rollback
CIt would commit anyway
DIt would end without commit or rollback
💡 Hint
Recall the key moment about rollback on errors and the flow after step 3
Concept Snapshot
Transactions in NestJS:
- Use dataSource.transaction(async manager => {...})
- All DB ops inside run atomically
- If all succeed, transaction commits
- If any fail, transaction rolls back
- Keeps data consistent and safe
Full Transcript
In NestJS, transactions let you group database operations so they all succeed or fail together. The flow starts a transaction, runs operations like saving user and profile, then checks for errors. If no errors, it commits the transaction to save changes permanently. If errors occur, it rolls back to undo all changes. The transaction state changes from None to Active when started, then to Committed if successful. This ensures your data stays consistent and avoids partial updates.

Practice

(1/5)
1. What is the main purpose of using transactions in a NestJS application with a database?
easy
A. To automatically generate database schemas
B. To ensure multiple database operations succeed or fail together
C. To speed up database queries by caching results
D. To log all database queries for debugging

Solution

  1. Step 1: Understand what transactions do

    Transactions group multiple database actions so they either all succeed or all fail, preventing partial updates.
  2. Step 2: Identify the purpose in NestJS context

    In NestJS, transactions keep data consistent by ensuring grouped operations are atomic.
  3. Final Answer:

    To ensure multiple database operations succeed or fail together -> Option B
  4. Quick Check:

    Transactions = atomic operations [OK]
Hint: Transactions keep grouped DB actions all-or-nothing [OK]
Common Mistakes:
  • Thinking transactions speed up queries
  • Confusing transactions with schema generation
  • Assuming transactions are for logging only
2. Which of the following is the correct way to start a transaction using TypeORM's DataSource in NestJS?
easy
A. dataSource.transaction(async (manager) => { /* operations */ })
B. dataSource.startTransaction(() => { /* operations */ })
C. dataSource.begin(async () => { /* operations */ })
D. dataSource.runTransaction(() => { /* operations */ })

Solution

  1. Step 1: Recall TypeORM transaction method

    TypeORM uses dataSource.transaction with an async callback to run transactional code.
  2. Step 2: Check method names

    Only dataSource.transaction(async (manager) => { /* operations */ }) uses the correct method name and async callback pattern.
  3. Final Answer:

    dataSource.transaction(async (manager) => { /* operations */ }) -> Option A
  4. Quick Check:

    Correct method is transaction with async callback [OK]
Hint: Use dataSource.transaction with async callback [OK]
Common Mistakes:
  • Using non-existent methods like startTransaction
  • Omitting async keyword in callback
  • Using wrong method names like begin or runTransaction
3. Given the following code snippet in a NestJS service using TypeORM, what will be the output if the second operation fails?
await dataSource.transaction(async (manager) => {
  await manager.save(user1);
  await manager.save(user2); // throws error
});
console.log('Transaction complete');
medium
A. Neither user1 nor user2 are saved, and an error is thrown before logging
B. Only user1 is saved, then 'Transaction complete' is logged
C. Both user1 and user2 are saved, then 'Transaction complete' is logged
D. 'Transaction complete' is logged before any save operations

Solution

  1. Step 1: Understand transaction rollback behavior

    If any operation inside the transaction fails, all changes are rolled back, so no data is saved.
  2. Step 2: Analyze the code flow

    The second save throws an error, so the transaction aborts and neither user1 nor user2 are saved. The error prevents reaching the console.log.
  3. Final Answer:

    Neither user1 nor user2 are saved, and an error is thrown before logging -> Option A
  4. Quick Check:

    Transaction rollback on error = no saves, error thrown [OK]
Hint: Error inside transaction rolls back all changes [OK]
Common Mistakes:
  • Assuming partial saves happen before error
  • Thinking console.log runs despite error
  • Believing transaction commits despite failure
4. Identify the error in this NestJS transaction code snippet:
await dataSource.transaction(async (manager) => {
  manager.save(user1);
  await manager.save(user2);
});
medium
A. dataSource.transaction requires a synchronous callback
B. Transaction callback should not be async
C. Missing await before manager.save(user1)
D. manager.save cannot be used inside transactions

Solution

  1. Step 1: Check async calls inside transaction

    All asynchronous operations inside the transaction callback must be awaited to ensure proper execution order.
  2. Step 2: Identify missing await

    The first save call lacks await, so it may not complete before the second save starts, causing unexpected behavior.
  3. Final Answer:

    Missing await before manager.save(user1) -> Option C
  4. Quick Check:

    Await all async DB calls inside transaction [OK]
Hint: Always await async DB calls inside transaction [OK]
Common Mistakes:
  • Omitting await on async calls
  • Thinking transaction callback can't be async
  • Believing manager.save is disallowed in transactions
5. You want to update two related entities atomically in NestJS using TypeORM transactions. Which approach correctly ensures both updates succeed or fail together?
async updateEntities(entityA, entityB) {
  await this.dataSource.transaction(async (manager) => {
    await manager.save(entityA);
    await manager.save(entityB);
  });
}
What is the best practice to handle errors and maintain data consistency?
hard
A. Manually call rollback() inside the transaction callback on error
B. Save entities without transactions and rely on database constraints
C. Use separate transactions for each save to isolate failures
D. Wrap the transaction call in try-catch and handle rollback automatically

Solution

  1. Step 1: Understand transaction error handling in TypeORM

    TypeORM automatically rolls back if an error is thrown inside the transaction callback.
  2. Step 2: Use try-catch outside transaction to handle errors

    Wrapping the transaction call in try-catch lets you catch errors and respond without manual rollback calls.
  3. Final Answer:

    Wrap the transaction call in try-catch and handle rollback automatically -> Option D
  4. Quick Check:

    Try-catch outside transaction handles errors; rollback is automatic [OK]
Hint: Use try-catch around transaction; rollback is automatic [OK]
Common Mistakes:
  • Trying to manually rollback inside transaction callback
  • Using separate transactions for related updates
  • Ignoring transactions and relying only on DB constraints
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard