Two-phase locking
Two-phase locking (2PL) is a widely used algorithm for implementing serializability in databases. Two-phase locking improves on Explicit Locks by making lock requirements much stronger.
In 2PL, several transactions are allowed to read the same object as long as nobody writes to the object. As soon as one of the transactions wants to update the object, it needs to acquire exclusive access. Once exclusive access has been granted, all other transactions have to wait, both read and write.
The two locking phases are why this implementation is called two-phase: the first-phase is when locks are acquired during transaction execution, and the second phase is when all locks are released at the end of the transaction.
This also means that writers don't just block other writers; they also block readers and vice versa. This is a crucial difference between Snapshot Isolation and two-phase locking. Even read-only transactions have to wait for write transactions to complete before they can get access to objects.
2PL is widely used but has downsides that prevent it from being the defacto standard for implementing Serializable Isolation mode. Applications using two-phase locking cannot scale well.