Add basic transactional support and optimistic locking

Registered by Kostja Osipov

Add basic transactional support by adding optimistic locking and tuple versions.

There is a global transaction counter, that only increments.

A connection that wishes to perform an update, first gets assigned a transaction identifier, based
on the current value of the counter. The counter is subsequently incremented.

Each tuple gets an additional internal field, called trx_id (transaction version), that records trx_id of the
transaction that last updated the tuple.

For simple updates, assignment of trx_id and update of the tuple is always atomic, (i.e. happens
in scope of the same fiber handling the same statement). This, in a way, provides "auto-commit"
mode of traditional transactional systems.

There is also a mechanism to start a multi-statement transaction. In that case, a connection
is assigned a trx id explicitly.

To provide for a clean implementation, we should consider
adding a separate "begin" and "commit" statements in the protocol, and implementing
multi-statement support in it. In that case, a client can pair "transaction begin"
with "select" and "transaction commit" with "update", and thus bear minimal performance overhead
for the user, while keeping the protocol explicit and clear.

Each update, then, is marked with that an explicitly assigned trx id.
If, at the moment of update, the transaction detects that the current trx id of the tuple
is greater than trx_id of the connection, the update is aborted with an error.

Similarly, for reads in a multi-statement transaction (e.g. SELECTs), if the trx id
of the tuple is greater than trx_id of the connection, the read is aborted with an error.

If a transaction performs more than one update, and some subsequent update has failed,
we do not roll back prior updates (thus, there is no transactional
atomicity in traditional sense). We can do that later by keeping a simple in-memory
undo log for a transaction. The undoing of the transaction is guaranteed to succeed
since each record that is being rolled back is marked with the trx id of the
transaction that is being rolled back, and thus can not be modified elsewhere.

@todo: consider adding the above option it in the same patch, even though
currently we have no users who need multi-statement transactions with more than
a single update.

@todo: to ensure transactional consistency, we'll also need to implement crash recovery that
rolls back incomplete transactions.

Blueprint information

Status:
Not started
Approver:
None
Priority:
Undefined
Drafter:
None
Direction:
Needs approval
Assignee:
None
Definition:
New
Series goal:
Accepted for 1.5
Implementation:
Unknown
Milestone target:
None

Related branches

Sprints

Whiteboard

(?)

Work Items

This blueprint contains Public information 
Everyone can see this information.

Subscribers

No subscribers.