@@ -5,74 +5,176 @@ package example_commands_test
5
5
import (
6
6
"context"
7
7
"fmt"
8
- "time"
9
8
10
9
"github.com/redis/go-redis/v9"
11
10
)
12
11
13
12
// HIDE_END
14
13
15
14
func ExampleClient_transactions () {
16
- // STEP_START basic_trans
17
15
ctx := context .Background ()
18
16
19
17
rdb := redis .NewClient (& redis.Options {
20
18
Addr : "localhost:6379" ,
21
19
Password : "" , // no password docs
22
20
DB : 0 , // use default DB
23
21
})
24
-
25
22
// REMOVE_START
26
- rdb .Del (ctx , "RateCounter" )
23
+ for i := 0 ; i < 5 ; i ++ {
24
+ rdb .Del (ctx , fmt .Sprintf ("seat:%d" , i ))
25
+ }
26
+
27
+ rdb .Del (ctx , "counter:1" , "counter:2" , "counter:3" , "shellpath" )
27
28
// REMOVE_END
28
29
29
- setResult , err := rdb .Set (ctx , "RateCounter" , 0 , 0 ).Result ()
30
+ // STEP_START basic_pipe
31
+ pipe := rdb .Pipeline ()
32
+
33
+ for i := 0 ; i < 5 ; i ++ {
34
+ pipe .Set (ctx , fmt .Sprintf ("seat:%v" , i ), fmt .Sprintf ("#%v" , i ), 0 )
35
+ }
36
+
37
+ cmds , err := pipe .Exec (ctx )
30
38
31
39
if err != nil {
32
40
panic (err )
33
41
}
34
42
35
- fmt .Println (setResult ) // >>> OK
43
+ for _ , c := range cmds {
44
+ fmt .Printf ("%v;" , c .(* redis.StatusCmd ).Val ())
45
+ }
46
+
47
+ fmt .Println ("" )
48
+ // >>> OK;OK;OK;OK;OK;
36
49
50
+ pipe = rdb .Pipeline ()
51
+
52
+ get0Result := pipe .Get (ctx , "seat:0" )
53
+ get3Result := pipe .Get (ctx , "seat:3" )
54
+ get4Result := pipe .Get (ctx , "seat:4" )
55
+
56
+ cmds , err = pipe .Exec (ctx )
57
+
58
+ // The results are available only after the pipeline
59
+ // has finished executing.
60
+ fmt .Println (get0Result .Val ()) // >>> #0
61
+ fmt .Println (get3Result .Val ()) // >>> #3
62
+ fmt .Println (get4Result .Val ()) // >>> #4
63
+ // STEP_END
64
+
65
+ // STEP_START basic_pipe_pipelined
66
+ var pd0Result * redis.StatusCmd
67
+ var pd3Result * redis.StatusCmd
68
+ var pd4Result * redis.StatusCmd
69
+
70
+ cmds , err = rdb .Pipelined (ctx , func (pipe redis.Pipeliner ) error {
71
+ pd0Result = (* redis .StatusCmd )(pipe .Get (ctx , "seat:0" ))
72
+ pd3Result = (* redis .StatusCmd )(pipe .Get (ctx , "seat:3" ))
73
+ pd4Result = (* redis .StatusCmd )(pipe .Get (ctx , "seat:4" ))
74
+ return nil
75
+ })
76
+
77
+ if err != nil {
78
+ panic (err )
79
+ }
80
+
81
+ // The results are available only after the pipeline
82
+ // has finished executing.
83
+ fmt .Println (pd0Result .Val ()) // >>> #0
84
+ fmt .Println (pd3Result .Val ()) // >>> #3
85
+ fmt .Println (pd4Result .Val ()) // >>> #4
86
+ // STEP_END
87
+
88
+ // STEP_START basic_trans
37
89
trans := rdb .TxPipeline ()
38
90
39
- // The values of `incrResult` and `expResult` are not available
40
- // until the transaction has finished executing.
41
- incrResult := trans .Incr (ctx , "RateCounter" )
42
- expResult := trans .Expire (ctx , "RateCounter" , time .Second * 10 )
91
+ trans .IncrBy (ctx , "counter:1" , 1 )
92
+ trans .IncrBy (ctx , "counter:2" , 2 )
93
+ trans .IncrBy (ctx , "counter:3" , 3 )
94
+
95
+ cmds , err = trans .Exec (ctx )
43
96
44
- cmdsExecuted , err := trans .Exec (ctx )
97
+ for _ , c := range cmds {
98
+ fmt .Println (c .(* redis.IntCmd ).Val ())
99
+ }
100
+ // >>> 1
101
+ // >>> 2
102
+ // >>> 3
103
+ // STEP_END
104
+
105
+ // STEP_START basic_trans_txpipelined
106
+ var tx1Result * redis.IntCmd
107
+ var tx2Result * redis.IntCmd
108
+ var tx3Result * redis.IntCmd
109
+
110
+ cmds , err = rdb .TxPipelined (ctx , func (trans redis.Pipeliner ) error {
111
+ tx1Result = trans .IncrBy (ctx , "counter:1" , 1 )
112
+ tx2Result = trans .IncrBy (ctx , "counter:2" , 2 )
113
+ tx3Result = trans .IncrBy (ctx , "counter:3" , 3 )
114
+ return nil
115
+ })
45
116
46
117
if err != nil {
47
118
panic (err )
48
119
}
49
120
50
- // Values are now available.
51
- fmt .Println (incrResult .Val ()) // >>> 1
52
- fmt .Println (expResult .Val ()) // >>> true
53
-
54
- // You can also use the array of command data returned
55
- // by the `Exec()` call.
56
- fmt .Println (len (cmdsExecuted )) // >>> 2
57
-
58
- fmt .Printf ("%v: %v\n " ,
59
- cmdsExecuted [0 ].Name (),
60
- cmdsExecuted [0 ].(* redis.IntCmd ).Val (),
61
- )
62
- // >>> incr: 1
63
-
64
- fmt .Printf ("%v: %v\n " ,
65
- cmdsExecuted [1 ].Name (),
66
- cmdsExecuted [1 ].(* redis.BoolCmd ).Val (),
67
- )
68
- // >>> expire: true
121
+ fmt .Println (tx1Result .Val ()) // >>> 2
122
+ fmt .Println (tx2Result .Val ()) // >>> 4
123
+ fmt .Println (tx3Result .Val ()) // >>> 6
124
+ // STEP_END
125
+
126
+ // STEP_START trans_watch
127
+ // Set initial value of `shellpath`.
128
+ rdb .Set (ctx , "shellpath" , "/usr/syscmds/" , 0 )
129
+
130
+ const maxRetries = 1000
131
+
132
+ // Retry if the key has been changed.
133
+ for i := 0 ; i < maxRetries ; i ++ {
134
+ err := rdb .Watch (ctx ,
135
+ func (tx * redis.Tx ) error {
136
+ currentPath , err := rdb .Get (ctx , "shellpath" ).Result ()
137
+ newPath := currentPath + ":/usr/mycmds/"
138
+
139
+ _ , err = tx .TxPipelined (ctx , func (pipe redis.Pipeliner ) error {
140
+ pipe .Set (ctx , "shellpath" , newPath , 0 )
141
+ return nil
142
+ })
143
+
144
+ return err
145
+ },
146
+ "shellpath" ,
147
+ )
148
+
149
+ if err == nil {
150
+ // Success.
151
+ break
152
+ } else if err == redis .TxFailedErr {
153
+ // Optimistic lock lost. Retry the transaction.
154
+ continue
155
+ } else {
156
+ // Panic for any other error.
157
+ panic (err )
158
+ }
159
+ }
160
+
161
+ fmt .Println (rdb .Get (ctx , "shellpath" ).Val ())
162
+ // >>> /usr/syscmds/:/usr/mycmds/
69
163
// STEP_END
70
164
71
165
// Output:
72
- // OK
166
+ // OK;OK;OK;OK;OK;
167
+ // #0
168
+ // #3
169
+ // #4
170
+ // #0
171
+ // #3
172
+ // #4
73
173
// 1
74
- // true
75
174
// 2
76
- // incr: 1
77
- // expire: true
175
+ // 3
176
+ // 2
177
+ // 4
178
+ // 6
179
+ // /usr/syscmds/:/usr/mycmds/
78
180
}
0 commit comments