Client
`transact`

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:

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:

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:

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:

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.