Pharos Triton
  • 🔱About Pharos Triton
  • 🏁Installing Pharos Triton
  • Apex Logging Basics
  • Common Apex Usage Patters
    • Batch Logging
    • Integration Logs
    • Apex Rest Logging
    • Full Control with TritonBuilder
  • Beyond Apex
    • LWC
    • 🔄LWC Transaction Management
    • ⚡LWC and Apex
    • 💾Platform Cache for Transactions
    • Flows
    • 〰️LWC, Apex and Flows
  • 📖Methods Reference
    • 📔Apex
      • Triton
      • TritonBuilder
      • TritonTypes
      • TritonLwc
        • ComponentLog
        • Component
        • Error
        • RuntimeInfo
      • TritonFlow
        • FlowLog
      • TritonHelper
        • PostProcessingControlsBuilder
      • LogBuilder
    • LWC
      • Triton
      • TritonBuilder
      • TritonUtils
  • Help and Support
Powered by GitBook
On this page
  • Automatic Transaction Management
  • Transaction Storage and Caching
  • Auto-Flush Mechanism
  • Transaction Methods
  • Best Practices
  1. Beyond Apex

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:

  1. Checks for an existing transaction ID in the session storage

  2. Creates a new transaction ID if none exists

  3. 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:

  1. Each log() call adds the entry to an internal buffer array in the Triton instance

  2. The transaction ID (stored in session storage) is automatically attached to each log

  3. The TransactionManager monitors the buffer every 10 seconds

  4. If any logs in the buffer are older than 1 minute, they are automatically flushed to the server

  5. 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():

  1. A new UUID v4 transaction ID is generated

  2. The ID is stored in session storage for cross-component access

  3. The auto-flush monitor is started (checks every 10 seconds for logs to flush)

  4. Any subsequent logs will use this new transaction ID

When you call resumeTransaction(existingTransactionId):

  1. The provided transaction ID is stored in session storage

  2. The auto-flush monitor is started

  3. Any subsequent logs will use this resumed transaction ID

  4. This is useful when you need to correlate logs with an existing transaction

When you call stopTransaction():

  1. Any pending logs are immediately flushed to the server

  2. The auto-flush monitor is stopped

  3. The transaction ID is removed from session storage

  4. 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:

  1. 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();
}
  1. 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

  1. Component Cleanup: Always clean up in the disconnectedCallback:

disconnectedCallback() {
    if (this.triton) {
        this.triton.flush();
        this.triton = undefined;
    }
}
  1. 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.

PreviousLWCNextLWC and Apex

Last updated 3 months ago

🔄