🔄LWC Transaction Management
Learn how Triton manages LWC transactions and logging sessions, including automatic transaction management and best practices.
Transaction management is a crucial aspect of logging in LWC components. Triton provides automated transaction handling that helps correlate logs across different operations and components. Let's explore how this works.
Automatic Transaction Management
Triton automatically manages transactions through its TransactionManager
class. When you create a new Triton instance, it automatically:
Checks for an existing transaction ID in the session storage
Creates a new transaction ID if none exists
Starts monitoring for log activity to handle auto-flushing
Here's how this initialization happens behind the scenes:
connectedCallback() {
this.triton = new Triton();
// Transaction ID is automatically managed
}
Transaction Storage and Caching
Triton uses session storage to maintain transaction continuity across component lifecycles. This is particularly useful when you have multiple components that need to share the same transaction context.
Here's an example showing how to leverage transaction caching:
export default class LogDemo extends LightningElement {
triton;
async handleOperation() {
try {
// Log the start of operation
this.triton.log(
this.triton.info(TYPE.FRONTEND, AREA.ACCOUNTS)
.summary('Operation started')
);
// Perform some async operation
await this.performOperation();
// Log successful completion
this.triton.log(
this.triton.info(TYPE.FRONTEND, AREA.ACCOUNTS)
.summary('Operation completed successfully')
);
} catch (error) {
// Log any errors that occur
this.triton.log(
this.triton.exception(error)
.summary('Operation failed')
);
}
}
}
Behind the scenes, here's what happens when these logs are created:
Each
log()
call adds the entry to an internal buffer array in the Triton instanceThe transaction ID (stored in session storage) is automatically attached to each log
The TransactionManager monitors the buffer every 10 seconds
If any logs in the buffer are older than 1 minute, they are automatically flushed to the server
All logs with the same transaction ID will be correlated in the database, allowing you to trace the entire operation
This buffering and auto-flush mechanism helps optimize performance by:
Reducing the number of server calls by batching logs together
Ensuring logs aren't lost if a component is destroyed
Maintaining transaction context across asynchronous operations
Automatically cleaning up old logs that might be forgotten
Auto-Flush Mechanism
Triton implements an intelligent auto-flush mechanism that automatically sends logs to the server based on activity patterns:
Checks for pending logs every 10 seconds
Automatically flushes logs that are older than 1 minute
Ensures logs aren't lost when components are destroyed
The auto-flush mechanism is particularly useful for long-running operations where you want to ensure logs are sent periodically:
export default class LogDemo extends LightningElement {
disconnectedCallback() {
if (this.triton) {
// Flush any remaining logs before disconnecting
this.triton.flush();
this.triton = undefined;
}
}
}
Transaction Methods
Triton provides several methods for manual transaction management when needed:
// Start a new transaction
this.triton.startTransaction();
// Resume an existing transaction
this.triton.resumeTransaction(existingTransactionId);
// Stop current transaction and flush logs
this.triton.stopTransaction();
When you call startTransaction()
:
A new UUID v4 transaction ID is generated
The ID is stored in session storage for cross-component access
The auto-flush monitor is started (checks every 10 seconds for logs to flush)
Any subsequent logs will use this new transaction ID
When you call resumeTransaction(existingTransactionId)
:
The provided transaction ID is stored in session storage
The auto-flush monitor is started
Any subsequent logs will use this resumed transaction ID
This is useful when you need to correlate logs with an existing transaction
When you call stopTransaction()
:
Any pending logs are immediately flushed to the server
The auto-flush monitor is stopped
The transaction ID is removed from session storage
This ensures all logs are properly saved before ending the transaction
These methods give you explicit control over transaction boundaries when needed, though in most cases, letting Triton handle transactions automatically is preferred.
Best Practices
Here are some recommended practices for transaction management in LWC:
Let Triton Handle It: In most cases, let Triton manage transactions automatically. The built-in management is sufficient for most use cases.
// Good - Let Triton handle transactions
connectedCallback() {
this.triton = new Triton();
}
Manual Transaction Control: Use manual transaction methods only when you need explicit control over transaction boundaries. Here are some common scenarios where manual transaction control makes sense:
// Scenario 1: Multi-step wizard where you want all steps logged under one transaction
async handleWizardNavigation() {
if (this.isFirstStep) {
this.triton.startTransaction(); // Start new transaction at wizard beginning
}
try {
// Log current step
this.triton.log(
this.triton.info(TYPE.FRONTEND, AREA.ACCOUNTS)
.summary(`Wizard Step ${this.currentStep} completed`)
);
await this.processCurrentStep();
if (this.isLastStep) {
// On last step, stop transaction and flush all wizard logs
this.triton.stopTransaction();
}
} catch (error) {
this.triton.stopTransaction(); // Clean up on error
throw error;
}
}
// Scenario 2: Batch processing UI where you want to group related operations
async handleBatchProcessing() {
this.triton.startTransaction();
try {
// Process multiple records in UI
for (const record of this.selectedRecords) {
this.triton.log(
this.triton.info(TYPE.FRONTEND, AREA.ACCOUNTS)
.summary(`Processing record ${record.Id}`)
);
await this.processRecord(record);
}
// All records processed - log summary and stop transaction
this.triton.log(
this.triton.info(TYPE.FRONTEND, AREA.ACCOUNTS)
.summary(`Batch processing complete: ${this.selectedRecords.length} records`)
);
} finally {
this.triton.stopTransaction();
}
}
In most other cases, letting Triton automatically manage transactions is the better choice. For example:
Single API calls or operations
Form submissions
Simple user interactions
Standard CRUD operations
Component Cleanup: Always clean up in the disconnectedCallback:
disconnectedCallback() {
if (this.triton) {
this.triton.flush();
this.triton = undefined;
}
}
Error Handling: Always include error handling with transaction management:
async handleOperation() {
try {
// Perform operation
await this.doSomething();
} catch (error) {
// Log error with current transaction
await this.triton.logNow(
this.triton.exception(error)
.summary('Operation failed')
);
}
}
By following these practices, you can ensure your LWC components maintain proper transaction context while logging, making it easier to trace and debug issues across your application.
Last updated