3 ms·
The alternative to 2PC is to have a compensating transaction log that always goes forward. The updates are recorded in the transaction log. Each update is the
by ww520 8y ago
The alternative to 2PC is to have a compensating transaction log that always goes forward. The updates are recorded in the transaction log. Each update is then shipped to the workers where they see if the update applied to them, and commit the ones relevant in their own databases. There's no rollback. A logical "rollback" can be applied by issuing a compensating transaction to negate the previous effect. E.g. issuing a new transaction of $10 debit to compensate for the previous transaction of $10 credit.
Example, a worker database maintains the Inventory table. Another worker database maintains the Order table. When the frontend app creates an order, it records the transaction [ (decrement part in Inventory), (create new record in Order) ] in the compensating transaction log. Note that both updates are in one transaction.
When the Inventory worker receives the transaction, it applies the update relevant to its tables, i.e. the Inventory table, and ignore the Order update. The Order worker receives the same transaction and applies the relevant Order update while ignoring the Inventory update in the transaction.
In the case of the order is canceled, a compensating transaction of [ (increment part in Inventory), (mark record as canceled in Order) ] can be created in the transaction log. The workers can pick up the transaction and apply the update relevant to them.
Both worker databases are de-coupled and can work in their own pace. They can crash can come back up without affecting the other. At the end of day, things are reconciled and are consistent.
The downside to this scheme is the timeliness of the data. One system can be down or slow to apply the updates and lag behind the other one.
- porpoisely 8y agoI may be mistaken, but I believe that's how transaction logs and rollbacks work in general. When you rollback a transaction, it doesn't remove the entry/action from the logs, rather it applies the negating transaction to the log. For an insert, it applies a delete. For a delete, it applies an insert. For an update, it applies an update of the previous value. The term rollback can be misleading since most people ( including myself ) would believe that the transaction is essentially erased and we go back to that point in time before the transaction.
- angry_octet 8y agoHmm, rollback means changing the state to one earlier in time. Sometimes that means reapplying data from the log to achieve a consistent state. After the log is applied there is no evidence of the failure. What you describe, with correcting entries, I would call a ledger system. This is what banks use.
- ww520 8y agoMost rdbms use the transaction log to store committed transactions, to perform redo in case of a crash. A transaction rollback simply aborts, throwing away any pending update in memory. The rollback transaction won't be written to the transaction log. There is no need to save aborted transactions. Aside from writing to the transaction log, writing the committed transactions to the tables can be complete, or partial in case of a crash. That is fine. During redo recovery, the DB starts from a well known state of the tables at a checkpoint of some time ago, reapplying the transactions from the log at the matching checkpoint position to the tables. Any previous partial updates due to the crash are overwritten. Checkpointing is done periodically to take a snapshot of the tables' state and to truncate the transaction log to avoid excessive long redo time.
- ww520 8y agoFurthermore some rdbms use the versioning scheme instead of the checkpoint system. In that case, each row in a table has multiple historic versions of the data value. Each version is tagged with the transaction id. The committed transaction is still saved to the transaction log. The updates to each table in the transaction are complete, or partial in case of a crash. In that case, some tables have missing data versions tagged with the transaction id. Due redo at recovery, it's just a matter of looking at the last applied transaction in the log, checking the table rows to see if they have the transaction id tagged versions. If the version exists, skip. If not, apply the update. There's no need to go further back to reapply older transactions. The versioning system is much faster than the checkpoint system in recovery. It also has the advantage of less lock contention in multi-user operations. But it needs periodic garbage collection (vacuuming) to delete the old versions from rows and compact the tables, which can be very expensive.