> For the complete documentation index, see [llms.txt](https://triton.pharos.ai/pharos-triton/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://triton.pharos.ai/pharos-triton/triton-best-practices/transaction-management.md).

# Transaction Management

## Transaction Handling & Correlation

* **Start early** (user entry points): `Triton.instance.startTransaction()` (Apex) or `triton.startTransaction()` (LWC).
* **Resume across hops:**
  * Capture the current **transactionId** in LWC (`triton.transactionId`) and pass it in Apex method params.
  * In Apex entry, call `Triton.instance.resumeTransaction(txId)` if provided; otherwise `withCache()` can auto-resume if configured.
* **Stop & flush** at natural boundaries: end of a long-running flow, batch `finish`, queueable completion, on modal close/navigation in LWC.

## Apex (Controller Entry)

```apex
@AuraEnabled(cacheable=false)
public static List<Opportunity> loadOpps(Id accountId, String txId) {
    if (String.isNotBlank(txId)) Triton.instance.resumeTransaction(txId);
    else Triton.instance.startTransaction();

    // Set up template for opportunity loading
    Triton.instance.setTemplate(
        Triton.makeBuilder()
            .category(TritonTypes.Category.Apex)
            .type(TritonTypes.Type.Backend)
            .area(TritonTypes.Area.OpportunityManagement)
            .relatedObject(accountId)
    );

    try {
        // ... do work
        Triton.instance.log(
            Triton.instance.fromTemplate()
                .level(TritonTypes.Level.INFO)
                .summary('Loaded opportunities')
                .details('accountId=' + accountId)
        );
        return [SELECT Id, Name, Amount FROM Opportunity WHERE AccountId = :accountId LIMIT 200];
    } catch (Exception e) {
        Triton.instance.log(
            Triton.instance.fromTemplate()
                .exception(e)
        );
        throw e;
    } finally {
        Triton.instance.stopTransaction();
    }
}
```

## LWC (Passing Transaction Across)

```js
import loadOpps from '@salesforce/apex/OppController.loadOpps';
const triton = new Triton().bindToComponent('c-opportunity-list');
const txId = triton.startTransaction();

// Set up template for opportunity operations
triton.setTemplate(
    triton.makeBuilder()
        .type(TYPE.FRONTEND)
        .area(AREA.OPPORTUNITY_MANAGEMENT)
        .relatedObjects([this.recordId])
);

try {
  const data = await loadOpps({ accountId: this.recordId, txId });
  triton.log(
    triton.fromTemplate()
      .summary('Opps rendered')
      .details(`rows=${data.length}`)
  );
} catch (error) {
  triton.logNow(
    triton.fromTemplate()
      .exception(error)
      .summary('Failed to load opps')
  );
} finally {
  triton.stopTransaction();
}
```

## Real-World Example: Multi-Step Lead Conversion Process

```js
// Lead conversion LWC with transaction correlation
export default class LeadConversionWizard extends LightningElement {
    triton;
    
    connectedCallback() {
        this.triton = new Triton().bindToComponent('c-lead-conversion-wizard');
        this.triton.startTransaction();
        
        // Set up template for lead conversion operations
        this.triton.setTemplate(
            this.triton.makeBuilder()
                .type(TYPE.FRONTEND)
                .area(AREA.LEAD_CONVERSION)
                .relatedObjects([this.recordId])
        );
    }
    
    async handleLeadConversion() {
        try {
            // Step 1: Validate lead data
            await this.validateLeadData();
            
            // Step 2: Create account and contact
            const accountResult = await createAccount({ 
                accountData: this.accountData,
                txId: this.triton.transactionId 
            });
            
            // Step 3: Create opportunity
            const oppResult = await createOpportunity({ 
                oppData: this.oppData,
                accountId: accountResult.Id,
                txId: this.triton.transactionId 
            });
            
            // Step 4: Update lead status
            await updateLeadStatus({ 
                leadId: this.recordId,
                status: 'Converted',
                txId: this.triton.transactionId 
            });
            
            this.triton.log(
                this.triton.fromTemplate()
                    .summary('Lead conversion completed')
                    .details(JSON.stringify({
                        accountId: accountResult.Id,
                        opportunityId: oppResult.Id,
                        leadId: this.recordId
                    }))
                    .relatedObjects([accountResult.Id, oppResult.Id])
            );
            
        } catch (error) {
            await this.triton.logNow(
                this.triton.fromTemplate()
                    .exception(error)
                    .summary('Lead conversion failed')
            );
        } finally {
            this.triton.stopTransaction();
        }
    }
}
```

```apex
// Apex controller with transaction resumption
public class LeadConversionController {
    @AuraEnabled
    public static Account createAccount(AccountData accountData, String txId) {
        // Resume transaction from LWC
        if (String.isNotBlank(txId)) {
            Triton.instance.resumeTransaction(txId);
        } else {
            Triton.instance.startTransaction();
        }
        
        // Set up template for lead conversion operations
        Triton.instance.setTemplate(
            Triton.makeBuilder()
                .category(TritonTypes.Category.Apex)
                .type(TritonTypes.Type.Backend)
                .area(TritonTypes.Area.LeadConversion)
                .relatedObject(accountData.leadId)
        );
        
        try {
            Account newAccount = new Account(
                Name = accountData.name,
                Industry = accountData.industry,
                BillingCity = accountData.city
            );
            insert newAccount;
            
            Triton.instance.log(
                Triton.instance.fromTemplate()
                    .level(TritonTypes.Level.INFO)
                    .summary('Account created for lead conversion')
                    .details('accountId=' + newAccount.Id + ', name=' + accountData.name)
                    .relatedObject(newAccount.Id)
            );
            
            return newAccount;
            
        } catch (Exception e) {
            Triton.instance.log(
                Triton.instance.fromTemplate()
                    .exception(e)
                    .summary('Account creation failed')
            );
            throw e;
        }
    }
}
```

## Transaction ID Flow

Understanding how the transaction ID connects logs across contexts is crucial:

1. **LWC Initialization**
   * Direct Params: Transaction ID is generated when first log is created
   * Cache: Transaction ID is generated and automatically cached
2. **Apex Execution**
   * Direct Params: Transaction ID is passed via method parameter and resumed
   * Cache: Transaction ID is automatically retrieved from cache
3. **Flow Execution**
   * The Flow's Interview GUID is automatically associated with the transaction
   * All Flow logs are grouped under the same transaction

## Best Practices

### Transaction Lifecycle

1. **Start early**: Begin transactions at user entry points
2. **Resume consistently**: Always resume transactions in Apex when txId is provided
3. **Stop properly**: End transactions at natural boundaries
4. **Handle failures**: Ensure transactions are stopped even when errors occur

### Correlation Strategies

1. **Direct parameter passing**: Explicitly pass transaction IDs for simple scenarios
2. **Platform cache**: Use cache for complex, multi-component scenarios
3. **Interview GUID**: Always use Flow Interview GUID for Flow correlation
4. **Error handling**: Maintain transaction context even during failures

### Performance Considerations

1. **Cache availability**: Check if platform cache is enabled before using cache-based correlation
2. **Memory management**: Be aware of transaction context memory usage in long-running processes
3. **Boundary management**: Stop transactions promptly to free resources

By mastering transaction management, you'll create complete execution traces that span across all Salesforce technologies, enabling powerful debugging and monitoring capabilities.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://triton.pharos.ai/pharos-triton/triton-best-practices/transaction-management.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
