Transaction Operations
Redis transactions allow executing multiple commands at once, ensuring atomicity. Commands in a transaction are either all executed or none are executed.
Multi - Start Transaction
vb
' Start transaction
oRedis.MultiExec - Commit Transaction
vb
' Commit transaction and get execution results
Dim vResults As Variant
vResults = oRedis.Exec()
If IsArray(vResults) Then
Dim i As Long
For i = 0 To UBound(vResults)
Debug.Print vResults(i)
Next
End IfDiscard - Cancel Transaction
vb
' Cancel transaction
oRedis.DiscardBasic Usage
Simple Transaction Example
vb
Sub SimpleTransaction()
Dim oRedis As New cRedisClient
If Not oRedis.Connect() Then
Debug.Print "Connection failed: " & oRedis.LastError
Exit Sub
End If
' Start transaction
oRedis.Multi
' Execute multiple commands (not executed immediately)
oRedis.Set_ "key1", "value1"
oRedis.Set_ "key2", "value2"
oRedis.Incr "counter"
' Commit transaction
Dim vResults As Variant
vResults = oRedis.Exec()
Debug.Print "Transaction execution results:"
If IsArray(vResults) Then
For i = 0 To UBound(vResults)
Debug.Print " Operation " & (i + 1) & " result: " & vResults(i)
Next
End If
oRedis.DisConnect
End SubUse Cases
1. Atomic Counter
vb
Sub AtomicCounter()
Dim oRedis As New cRedisClient
If Not oRedis.Connect() Then Exit Sub
' Initialize counter
oRedis.Set_ "counter", "0"
Debug.Print "Initial count: " & oRedis.Get_("counter")
' Start transaction
oRedis.Multi
' Execute multiple increment operations
oRedis.Incr "counter"
oRedis.Incr "counter"
oRedis.Incr "counter"
' Commit transaction
Dim vResults As Variant
vResults = oRedis.Exec()
Debug.Print vbCrLf & "Transaction execution results:"
If IsArray(vResults) Then
For i = 0 To UBound(vResults)
Debug.Print " Operation " & (i + 1) & " result: " & vResults(i)
Next
End If
Debug.Print "Final count: " & oRedis.Get_("counter")
oRedis.DisConnect
End Sub2. Bank Transfer
vb
Sub BankTransfer()
Dim oRedis As New cRedisClient
If Not oRedis.Connect() Then Exit Sub
' Initialize account balances
oRedis.Set_ "account:A", "1000"
oRedis.Set_ "account:B", "500"
Debug.Print "Before transfer:"
Debug.Print " Account A: " & oRedis.Get_("account:A")
Debug.Print " Account B: " & oRedis.Get_("account:B")
Dim lAmount As Long
lAmount = 200
' Start transaction
oRedis.Multi
' Deduct from account A
oRedis.DecrBy "account:A", lAmount
' Add to account B
oRedis.IncrBy "account:B", lAmount
' Commit transaction
Dim vResults As Variant
vResults = oRedis.Exec()
Debug.Print vbCrLf & "After transfer:"
Debug.Print " Account A: " & oRedis.Get_("account:A")
Debug.Print " Account B: " & oRedis.Get_("account:B")
oRedis.DisConnect
End Sub3. Batch Update
vb
Sub BatchUpdate()
Dim oRedis As New cRedisClient
If Not oRedis.Connect() Then Exit Sub
' Start transaction
oRedis.Multi
' Batch set multiple keys
oRedis.Set_ "user:1", "Zhang San"
oRedis.Set_ "user:2", "Li Si"
oRedis.Set_ "user:3", "Wang Wu"
oRedis.Set_ "user:4", "Zhao Liu"
oRedis.Set_ "user:5", "Qian Qi"
' Batch set expiration times
oRedis.Expire "user:1", 3600
oRedis.Expire "user:2", 3600
oRedis.Expire "user:3", 3600
oRedis.Expire "user:4", 3600
oRedis.Expire "user:5", 3600
' Commit transaction
Dim vResults As Variant
vResults = oRedis.Exec()
Debug.Print "Batch update completed, executed " & (UBound(vResults) + 1) & " operations"
oRedis.DisConnect
End Sub4. Conditional Update
vb
Sub ConditionalUpdate()
Dim oRedis As New cRedisClient
If Not oRedis.Connect() Then Exit Sub
' Initialize stock
oRedis.Set_ "product:1001:stock", "10"
Debug.Print "Initial stock: " & oRedis.Get_("product:1001:stock")
Dim lBuyAmount As Long
lBuyAmount = 3
' Check if stock is sufficient
Dim lCurrentStock As Long
lCurrentStock = CLng(oRedis.Get_("product:1001:stock"))
If lCurrentStock >= lBuyAmount Then
' Stock sufficient, start transaction
oRedis.Multi
' Reduce stock
oRedis.DecrBy "product:1001:stock", lBuyAmount
' Increase sales
oRedis.IncrBy "product:1001:sold", lBuyAmount
' Record sales log
oRedis.RPush "sales:log", "Sold " & lBuyAmount & " items"
' Commit transaction
Dim vResults As Variant
vResults = oRedis.Exec()
Debug.Print vbCrLf & "Purchase successful!"
Debug.Print "Remaining stock: " & oRedis.Get_("product:1001:stock")
Debug.Print "Total sold: " & oRedis.Get_("product:1001:sold")
Else
Debug.Print "Insufficient stock, cannot purchase"
End If
oRedis.DisConnect
End Sub5. Data Consistency Check
vb
Sub DataConsistency()
Dim oRedis As New cRedisClient
If Not oRedis.Connect() Then Exit Sub
' Initialize data
oRedis.HSet "order:1001", "amount", "100"
oRedis.HSet "order:1001", "status", "pending"
oRedis.HSet "order:1001", "user", "user:123"
oRedis.HSet "user:123", "balance", "500"
' Start transaction
oRedis.Multi
' Get order amount
oRedis.HGet "order:1001", "amount"
' Get user balance
oRedis.HGet "user:123", "balance"
' Execute transaction to get data
Dim vResults As Variant
vResults = oRedis.Exec()
' Check if balance is sufficient
If IsArray(vResults) And UBound(vResults) >= 1 Then
Dim lOrderAmount As Long
Dim lUserBalance As Long
lOrderAmount = CLng(vResults(0))
lUserBalance = CLng(vResults(1))
If lUserBalance >= lOrderAmount Then
' Balance sufficient, execute payment
oRedis.Multi
' Deduct user balance
oRedis.HSet "user:123", "balance", CStr(lUserBalance - lOrderAmount)
' Update order status
oRedis.HSet "order:1001", "status", "paid"
' Record payment log
oRedis.RPush "payment:log", "Order 1001 payment " & lOrderAmount
' Commit transaction
vResults = oRedis.Exec()
Debug.Print "Payment successful"
Debug.Print "Remaining balance: " & oRedis.HGet("user:123", "balance")
Debug.Print "Order status: " & oRedis.HGet("order:1001", "status")
Else
Debug.Print "Insufficient balance, payment failed"
End If
End If
oRedis.DisConnect
End Sub6. Cancel Transaction
vb
Sub CancelTransaction()
Dim oRedis As New cRedisClient
If Not oRedis.Connect() Then Exit Sub
' Initialize data
oRedis.Set_ "counter", "10"
Debug.Print "Initial value: " & oRedis.Get_("counter")
' Start transaction
oRedis.Multi
' Execute multiple operations
oRedis.Incr "counter"
oRedis.Incr "counter"
oRedis.Incr "counter"
' Cancel transaction
oRedis.Discard
Debug.Print "Value after canceling transaction: " & oRedis.Get_("counter")
oRedis.DisConnect
End SubTransaction Features
1. Atomicity
Commands in a transaction are either all executed or none are executed:
vb
Sub AtomicityExample()
Dim oRedis As New cRedisClient
If Not oRedis.Connect() Then Exit Sub
oRedis.Multi
' These commands either all succeed or all fail
oRedis.Set_ "key1", "value1"
oRedis.Set_ "key2", "value2"
oRedis.Set_ "key3", "value3"
oRedis.Exec
oRedis.DisConnect
End Sub2. Isolation
During transaction execution, other clients cannot see intermediate states:
vb
Sub IsolationExample()
Dim oRedis As New cRedisClient
If Not oRedis.Connect() Then Exit Sub
' Set initial value
oRedis.Set_ "balance", "100"
' Start transaction
oRedis.Multi
' Decrease balance (other clients still see 100 at this point)
oRedis.Decr "balance"
' Can do other operations here...
' Commit transaction (other clients can now see changes)
oRedis.Exec
oRedis.DisConnect
End SubNotes
- No Rollback: Redis transactions do not support rollback; even if a command fails, other commands will still be executed
- Error Handling: Validate parameters before executing transaction
- Performance Consideration: Transactions block other operations, avoid long-running transactions
- Nested Transactions: Redis does not support nested transactions
- Optimistic Locking: Can use
WATCHcommand to implement optimistic locking (requires extended implementation)
Complete Example
vb
Sub Example_Transaction()
Dim oRedis As New cRedisClient
If Not oRedis.Connect() Then
Debug.Print "Connection failed: " & oRedis.LastError
Exit Sub
End If
' Initialize counter
oRedis.Set_ "counter", "0"
Debug.Print "Initial count: " & oRedis.Get_("counter")
' Start transaction
oRedis.Multi
' Execute multiple increment operations
oRedis.Incr "counter"
oRedis.Incr "counter"
oRedis.Incr "counter"
' Commit transaction
Dim vResults As Variant
vResults = oRedis.Exec()
Debug.Print "Transaction execution results:"
If IsArray(vResults) Then
For i = 0 To UBound(vResults)
Debug.Print " Operation " & (i + 1) & " result: " & vResults(i)
Next
End If
Debug.Print "Final count: " & oRedis.Get_("counter")
oRedis.DisConnect
End SubTransaction vs Single Command
| Scenario | Recommended Method | Reason |
|---|---|---|
| Single operation | Single command | Simple and direct |
| Multiple related ops | Transaction | Ensure atomicity |
| Unrelated operations | Single command | Reduce blocking |
| Need intermediate results | Step-by-step | More flexible |
| Batch update | Transaction or batch commands | Improve performance |