Skip to main content

Transactions

This item is only intended to be used by the module's authors. Private

Provides functionality for reading data that might be involved in an ongoing, uncommitted transaction initiated by Store:tx().

NOTE

This module only contains the implementation for Transactions.readTx. Writing transactions is handled in Store:tx

Purpose: When a Store:tx() operation begins, it might involve multiple steps (e.g., reading current data, applying changes, writing back). If a server crashes before the transaction is fully committed or rolled back, this module helps determine the correct state to return.

It checks the status of the transaction ID (txId) stored separately in the DataStore. If the transaction is still pending (represented as false) or has failed, it returns the last known committed data. If the transaction has successfully committed (represented as nil), it applies the transaction's patch (txPatch) to the previously committed data (committedData) to return the newly committed state.

This ensures that readers either get the stable state before the transaction or the final state after a successful transaction, avoiding inconsistent intermediate states.

Types

ReadTxParams

interface ReadTxParams {
storeDataStore--

The DataStore instance where transaction status markers are stored.

txInfoTypes.TxInfo--

The transaction information associated with the data being read.

}

Parameters required for the readTx function.

Functions

readTx

Transactions.readTx(
paramsReadTxParams--

The parameters for the read operation.

) → Promise<any>--

A Promise that resolves with the appropriate data (either committed or patched).

Reads data, considering the status of an associated transaction.

Checks the status of the transaction ID (txInfo.txId) in the DataStore.

  • If txId is nil (meaning no transaction was associated or it was cleaned up), returns the committedData directly.
  • If txId exists:
    • Fetches the status from the DataStore using the txId as the key.
    • Status Convention:
      • nil: The transaction successfully committed. The corresponding txPatch should be applied to committedData.
      • false: The transaction is still in progress or failed/rolled back. The committedData (state before the transaction) should be returned.
    • Applies the patch if the status is nil and a patch exists.
    • Returns committedData if the status is false.

Using nil to indicate a successful transaction allows for easier cleanup of transaction markers in the DataStore. Instead of setting the marker to true and only removing it after the txId is no longer needed, we can simply delete the marker immediately after a successful transaction.

Errors

TypeDescription
stringRejects if the transaction status indicates commitment (`nil`) but the `txPatch` is missing, or if DataStore operations fail (via `dataStoreRetry`). Propagates errors from `DataStore:GetAsync` via `dataStoreRetry`.
Show raw api
{
    "functions": [
        {
            "name": "readTx",
            "desc": "Reads data, considering the status of an associated transaction.\n\nChecks the status of the transaction ID (`txInfo.txId`) in the DataStore.\n- If `txId` is nil (meaning no transaction was associated or it was cleaned up),\n  returns the `committedData` directly.\n- If `txId` exists:\n\t- Fetches the status from the DataStore using the `txId` as the key.\n\t- **Status Convention:**\n\t\t- `nil`: The transaction successfully committed. The corresponding `txPatch`\n\t\t  should be applied to `committedData`.\n\t\t- `false`: The transaction is still in progress or failed/rolled back. The\n\t\t  `committedData` (state before the transaction) should be returned.\n\t- Applies the patch if the status is `nil` and a patch exists.\n\t- Returns `committedData` if the status is `false`.\n\nUsing `nil` to indicate a successful transaction allows for easier cleanup of\ntransaction markers in the DataStore. Instead of setting the marker to `true`\nand only removing it after the `txId` is no longer needed, we can simply delete\nthe marker immediately after a successful transaction.",
            "params": [
                {
                    "name": "params",
                    "desc": "The parameters for the read operation.",
                    "lua_type": "ReadTxParams"
                }
            ],
            "returns": [
                {
                    "desc": "A Promise that resolves with the appropriate data (either committed or patched).",
                    "lua_type": "Promise<any>"
                }
            ],
            "function_type": "static",
            "errors": [
                {
                    "lua_type": "string",
                    "desc": "Rejects if the transaction status indicates commitment (`nil`) but the `txPatch` is missing, or if DataStore operations fail (via `dataStoreRetry`). Propagates errors from `DataStore:GetAsync` via `dataStoreRetry`."
                }
            ],
            "source": {
                "line": 75,
                "path": "src/Transactions.luau"
            }
        }
    ],
    "properties": [],
    "types": [
        {
            "name": "ReadTxParams",
            "desc": "Parameters required for the `readTx` function.",
            "fields": [
                {
                    "name": "store",
                    "lua_type": "DataStore",
                    "desc": "The DataStore instance where transaction status markers are stored."
                },
                {
                    "name": "txInfo",
                    "lua_type": "Types.TxInfo",
                    "desc": "The transaction information associated with the data being read."
                }
            ],
            "source": {
                "line": 40,
                "path": "src/Transactions.luau"
            }
        }
    ],
    "name": "Transactions",
    "desc": "Provides functionality for reading data that might be involved in an ongoing,\nuncommitted transaction initiated by `Store:tx()`.\n\n:::note\nThis module only contains the implementation for [Transactions.readTx]. Writing transactions is handled in [Store:tx]\n:::\n\n**Purpose:** When a `Store:tx()` operation begins, it might involve multiple steps\n(e.g., reading current data, applying changes, writing back). If a server crashes\n*before* the transaction is fully committed or rolled back, this module helps\ndetermine the correct state to return.\n\nIt checks the status of the transaction ID (`txId`) stored separately in the DataStore.\nIf the transaction is still pending (represented as `false`) or has failed, it returns the last known\n*committed* data. If the transaction has successfully committed (represented as `nil`), it applies the\ntransaction's patch (`txPatch`) to the previously committed data (`committedData`)\nto return the *newly* committed state.\n\nThis ensures that readers either get the stable state before the transaction or the\nfinal state after a successful transaction, avoiding inconsistent intermediate states.",
    "private": true,
    "source": {
        "line": 26,
        "path": "src/Transactions.luau"
    }
}