Skip to content

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.Multi

Exec - 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 If

Discard - Cancel Transaction

vb
' Cancel transaction
oRedis.Discard

Basic 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 Sub

Use 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 Sub

2. 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 Sub

3. 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 Sub

4. 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 Sub

5. 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 Sub

6. 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 Sub

Transaction 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 Sub

2. 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 Sub

Notes

  1. No Rollback: Redis transactions do not support rollback; even if a command fails, other commands will still be executed
  2. Error Handling: Validate parameters before executing transaction
  3. Performance Consideration: Transactions block other operations, avoid long-running transactions
  4. Nested Transactions: Redis does not support nested transactions
  5. Optimistic Locking: Can use WATCH command 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 Sub

Transaction vs Single Command

ScenarioRecommended MethodReason
Single operationSingle commandSimple and direct
Multiple related opsTransactionEnsure atomicity
Unrelated operationsSingle commandReduce blocking
Need intermediate resultsStep-by-stepMore flexible
Batch updateTransaction or batch commandsImprove performance

VB6 and LOGO copyright of Microsoft Corporation