4.14.1.1 Transactions
AllApplicationManualNameSummaryHelp

  • Documentation
    • Reference manual
      • Built-in Predicates
        • Database
          • Managing (dynamic) predicates
            • Transactions
              • transaction/1
              • transaction/2
              • transaction/3
              • snapshot/1
              • current_transaction/1
              • transaction_updates/1
    • Packages
Availability:built-in
Sourcetransaction(:Goal)
transaction(:Goal, +Options)
Run Goal as once/1 in a transaction. This implies that access to dynamic predicates‘sees' the dynamic predicates at the moment the transaction is started, together with the modifications issued by Goal. Thus, Goal does not see changes to dynamic predicates from other threads and other threads do not see modifications by Goal (isolation). If Goal succeeds, all modifications become atomically visible to the other threads. If Goal fails or raises an exception all local modifications are discarded and transaction/1 fails or passes the exception.

Currently the number of database changes inside a transaction (or snapshot, see snapshot/1) is limited to 2 ** 32 -1. If this limit is exceeded a representation_error(transaction_generations) exception is raised.

Transactions may be nested. The above mentioned limitation for the number of database changes applies to the combined number in nested transactions.

If Goal succeeds, the transaction is committed. This implies that (1) any clause that is asserted in the transaction and not retracted in the same transaction is made globally visible and (2) and clause the existed before the transaction and is retracted in the transaction becomes globally invisible. Multiple transactions may retract the same clause and be committed, i.e., committing a retract that was already performed is a no-op. All modifications become atomically visible to other threads. The transaction/3 variation allows for verifying constraints just before the commit takes place.

Clause ordering Inside a transaction clauses can be added using asserta/1 and assertz/1. If only a single transaction is active at any point in time transactions preserve the usual ordering of clauses. However, if multiple transactions manipulate the same predicate(s) concurrently (typically using transaction/3), the final order of the clauses is the order in which the transactions asserted the clauses and not the order in which the transactions are committed.

The transaction/1 variant is equivalent to transaction(Goal,[]). The transaction/2 variant processed the following options:

bulk(+Boolean)
When true, accumulate events from changes to dynamic predicates (see prolog_listen/2) and trigger these events as part of the commit phase. This implies that if the transaction is not committed the events are never triggered. Failure to trigger the events causes the transaction to be discarded. Experimental.