97 Transactions
The syntax for transaction control depends on the host language. Transactions apply to database-state updates, not to ordinary local program-state updates. Semantically, a transaction is opened on a single data partition before database-state update statements are performed. Those statements transform the current transaction state for that partition.
A database-state update statement requires an open transaction. A statement whose target would update data outside the open transaction's partition is not a valid partition-local update.
The transaction state need not be a disk-resident copy of the partition. An implementation may represent a partition as in-memory objects, mutate those objects during the transaction, and record which objects became dirty. Dirty-object sets, redo logs, log-structured stores, snapshots, and copy-on-write pages are physical strategies. They are valid when reads observe the specified pre-state and post-state, commit accepts exactly the final database state, and recovery preserves transaction atomicity.
A local program-state update writes only program locations. It does not require an open transaction and is not committed or rolled back by the database transaction mechanism. It is still subject to the static update-formation rules: the target must be assignable, and the replacement expression must be statically compatible with the target's element type and cardinality. Declared constraints are not required to hold for the resulting ordinary program state.
Constraints apply at the final transaction boundary, not after each update statement. A transaction may contain intermediate states that violate constraints, provided the transaction's final state satisfies the applicable constraints when the transaction is committed.
Per-statement constraint checking would be too strong for construction of shared identities. For example, creating a shipment that refers to an existing supplier and part may require several mutations before the supplier, part, and shipment predicates are again mutually consistent. The transaction boundary, not each individual mutation, is the point where the constrained database state is accepted or rejected.
The final state at commit is a constraint boundary. A program that attempts to commit a state violating an applicable constraint is illegal. Predica does not prescribe a runtime check, exception, trap, rollback, or other execution behaviour for that violation. See Constraint-Violating Updates.
A DBMS that supports failure recovery must ensure transactions are atomic. After recovery from a failure, a transaction's effects are either all present or all absent.
Partition Constraints
Predica transactions do not use distributed atomic commit to enforce invariants across unrelated partitions. If an invariant must be enforced transactionally, the data needed to decide that invariant belongs in a single partition.
Relationships that cross partition boundaries are therefore maintained by read-only models, replication, projections, asynchronous derivations, or messages between partition owners. Those mechanisms may detect and report cross-partition facts, but they are not a substitute for a single transaction that atomically updates multiple partitions.
Concurrency Model
Strict two-phase locking is not the preferred concurrency model for a Predica DBMS. A system whose normal operation depends on deadlock detection, victim selection, and rollback has made rollback part of ordinary concurrency control rather than an exceptional recovery mechanism.
A Predica DBMS is expected to favour architectures where ownership and concurrency are made explicit by partitioning. A database may be embedded within a process; its data may be divided into partitions; and each partition may be protected by its own exclusive lock or by an actor that serialises all operations for that partition.
Transactions are scoped to single partitions. A transaction that spans multiple partitions inside one process is a design to avoid. Distributed transactions are a particularly poor fit for this model.
Concurrency between partitions is then handled by design patterns that avoid global lock cycles: replication, master-slave ownership, operational transformation, MVCC, snapshot isolation, and message passing between partition actors. These techniques do not remove the requirement for transactional atomicity inside each partition; they shape how a DBMS obtains concurrency without making cross-partition atomic commit the normal mechanism.
Read-only Constraints
The single-partition transaction rule is compatible with stronger global views because those views are read-only. The general pattern is described in read-only models over weakly constrained data.