---
description: How to use the TriplitClient transact method to update a Triplit database atomically.
---

# transact

Transactions are a way to group multiple mutations into a single atomic operation. If any part of the mutations fail, the entire transaction is rolled back.

A transaction can be created by calling `client.transact()`. For example:

```typescript
await client.transact(async (tx) => {
  await tx.insert('employee', { id: 'Fry', name: 'Philip J. Fry' });
  await tx.insert('employee', { id: 'Leela', name: 'Turanga Leela' });
  await tx.insert('employee', {
    id: 'Bender',
    name: 'Bender Bending Rodriguez',
  });
});
```

If you decide you need to abort a transaction, you can call `cancel` inside your transaction. For example:

```typescript
await client.transact(async (tx) => {
  await tx.insert('employee', { id: 'Hermes', name: 'Hermes Conrad' });
  await tx.cancel();
});
```

## Error and success handling

Mutations are first run on Triplit's local cache "optimistically", returning a promise. If the optimistic mutation is successful, the promise will resolve with the id of the transaction. If the optimistic mutation fails, the promise will reject with an error. So you can handle optimistic updates with standard promise handling. For example:

```typescript
try {
  const { txId } = await client.insert('employee', {
    id: 'Fry',
    name: 'Philip J. Fry',
  });
  // Optimistic update succeeded
} catch (e) {
  // Optimistic update failed
}
```

If the sync engine is connected, mutations will then be applied to the server when possible. To react to a transaction successfully running or failing on the server, you can pass a callback to `client.syncEngine.onTxCommit(txId, callback)` or `client.syncEngine.onTxFailure(txId, callback)`. The client also provides methods for helping you manage what should happen to your data if a transaction fails on the server. `client.syncEngine.retry(txId)` will retry a transaction with the id `txId`. `client.syncEngine.rollback(txId)` will rollback a transaction with the id `txId`, removing it from the local cache. For example:

```typescript
const { txId } = await client.insert('employee', {
  id: 'Fry',
  name: 'Philip J. Fry',
});
client.syncEngine.onTxCommit(txId, () => {
  // Transaction succeeded on the server
});
client.syncEngine.onTxFailure(txId, (e) => {
  // Transaction failed on the server
  // shouldRetry is a boolean you define
  if (shouldRetry) {
    client.syncEngine.retry(txId);
  } else {
    client.syncEngine.rollback(txId);
  }
});
```

Triplit's API attempts to give you the flexibility to handle errors in various ways. For example, you could choose to retry a transaction a certain number of times before rolling it back. Or you could choose to retry a transaction only if it failed due to a network error.
