4 "github.com/go-redis/redis/internal/pool"
5 "github.com/go-redis/redis/internal/proto"
8 // TxFailedErr transaction redis failed.
9 const TxFailedErr = proto.RedisError("redis: transaction failed")
11 // Tx implements Redis transactions as described in
12 // http://redis.io/topics/transactions. It's NOT safe for concurrent use
13 // by multiple goroutines, because Exec resets list of watched keys.
14 // If you don't need WATCH it is better to use Pipeline.
20 func (c *Client) newTx() *Tx {
22 baseClient: baseClient{
24 connPool: pool.NewStickyConnPool(c.connPool.(*pool.ConnPool), true),
28 tx.statefulCmdable.setProcessor(tx.Process)
32 // Watch prepares a transaction and marks the keys to be watched
33 // for conditional execution if there are any keys.
35 // The transaction is automatically closed when fn exits.
36 func (c *Client) Watch(fn func(*Tx) error, keys ...string) error {
39 if err := tx.Watch(keys...).Err(); err != nil {
50 // Close closes the transaction, releasing any open resources.
51 func (c *Tx) Close() error {
53 return c.baseClient.Close()
56 // Watch marks the keys to be watched for conditional execution
58 func (c *Tx) Watch(keys ...string) *StatusCmd {
59 args := make([]interface{}, 1+len(keys))
61 for i, key := range keys {
64 cmd := NewStatusCmd(args...)
69 // Unwatch flushes all the previously watched keys for a transaction.
70 func (c *Tx) Unwatch(keys ...string) *StatusCmd {
71 args := make([]interface{}, 1+len(keys))
73 for i, key := range keys {
76 cmd := NewStatusCmd(args...)
81 // Pipeline creates a new pipeline. It is more convenient to use Pipelined.
82 func (c *Tx) Pipeline() Pipeliner {
84 exec: c.processTxPipeline,
86 pipe.statefulCmdable.setProcessor(pipe.Process)
90 // Pipelined executes commands queued in the fn in a transaction.
92 // When using WATCH, EXEC will execute commands only if the watched keys
93 // were not modified, allowing for a check-and-set mechanism.
95 // Exec always returns list of commands. If transaction fails
96 // TxFailedErr is returned. Otherwise Exec returns an error of the first
97 // failed command or nil.
98 func (c *Tx) Pipelined(fn func(Pipeliner) error) ([]Cmder, error) {
99 return c.Pipeline().Pipelined(fn)
102 // TxPipelined is an alias for Pipelined.
103 func (c *Tx) TxPipelined(fn func(Pipeliner) error) ([]Cmder, error) {
104 return c.Pipelined(fn)
107 // TxPipeline is an alias for Pipeline.
108 func (c *Tx) TxPipeline() Pipeliner {