Transactions in Redis are simple and yet hard to implement in a multi-threaded environment.
The first improvement that must happen is that Entry::Version must be introduced in order to support WATCH/UNWATCH commands (done in 54ff9b2). Each connection keeps track of key's versions if anything changes the execution of a transaction fails a Null is returned. The official documentation explains very well this concept.
The second improvement that must be introduced is an early args parsing. From this parsing all affected keys must be extracted (this can be achieved with the command definition and the first key, last key and step keys). Also any syntax error must prevent a command to be queued. Right now all this is happening in each command controllers, that won't change, but we need to extract all affected keys and valid the syntax without invoking the commands controllers.
Lastly to keep Redis promises of isolating changes, the list of affected keys by the transaction must be locked exclusively while EXEC is running. This is easily doable by adding another locking mechanism in at the the Db struct. It would be pretty inefficient to lock all other connections while executing a transaction, we only need to look the affected keys.
Transactions in Redis are simple and yet hard to implement in a multi-threaded environment.
The first improvement that must happen is that
Entry::Version
must be introduced in order to support WATCH/UNWATCH commands (done in 54ff9b2). Each connection keeps track of key's versions if anything changes the execution of a transaction fails aNull
is returned. The official documentation explains very well this concept.The second improvement that must be introduced is an early
args
parsing. From this parsing all affected keys must be extracted (this can be achieved with the command definition and thefirst key
,last key
andstep
keys). Also any syntax error must prevent a command to be queued. Right now all this is happening in each command controllers, that won't change, but we need to extract all affected keys and valid the syntax without invoking the commands controllers.Lastly to keep Redis promises of isolating changes, the list of affected keys by the transaction must be locked exclusively while
EXEC
is running. This is easily doable by adding another locking mechanism in at the the Db struct. It would be pretty inefficient to lock all other connections while executing a transaction, we only need to look the affected keys.Commands to support: