1
0
mirror of https://github.com/Luzifer/cloudkeys-go.git synced 2024-09-20 08:02:57 +00:00
cloudkeys-go/vendor/github.com/xuyu/goredis/transactions.go

105 lines
2.7 KiB
Go

package goredis
import (
"errors"
)
// Transaction doc: http://redis.io/topics/transactions
// MULTI, EXEC, DISCARD and WATCH are the foundation of transactions in Redis.
// A Redis script is transactional by definition,
// so everything you can do with a Redis transaction, you can also do with a script,
// and usually the script will be both simpler and faster.
type Transaction struct {
redis *Redis
conn *connection
}
// Transaction new a *transaction from *redis
func (r *Redis) Transaction() (*Transaction, error) {
c, err := r.pool.Get()
if err != nil {
return nil, err
}
if err := c.SendCommand("MULTI"); err != nil {
r.pool.Put(c)
return nil, err
}
if _, err := c.RecvReply(); err != nil {
r.pool.Put(c)
return nil, err
}
return &Transaction{r, c}, nil
}
// Close closes the transaction, put the under connection back for reuse
func (t *Transaction) Close() {
t.redis.pool.Put(t.conn)
}
// Discard flushes all previously queued commands in a transaction
// and restores the connection state to normal.
// If WATCH was used, DISCARD unwatches all keys.
func (t *Transaction) Discard() error {
if err := t.conn.SendCommand("DISCARD"); err != nil {
return err
}
_, err := t.conn.RecvReply()
return err
}
// Watch marks the given keys to be watched for conditional execution of a transaction.
func (t *Transaction) Watch(keys ...string) error {
args := packArgs("WATCH", keys)
if err := t.conn.SendCommand(args...); err != nil {
return err
}
_, err := t.conn.RecvReply()
return err
}
// UnWatch flushes all the previously watched keys for a transaction.
// If you call EXEC or DISCARD, there's no need to manually call UNWATCH.
func (t *Transaction) UnWatch() error {
if err := t.conn.SendCommand("UNWATCH"); err != nil {
return err
}
_, err := t.conn.RecvReply()
return err
}
// Exec executes all previously queued commands in a transaction
// and restores the connection state to normal.
// When using WATCH, EXEC will execute commands only if the watched keys were not modified,
// allowing for a check-and-set mechanism.
func (t *Transaction) Exec() ([]*Reply, error) {
if err := t.conn.SendCommand("EXEC"); err != nil {
return nil, err
}
rp, err := t.conn.RecvReply()
if err != nil {
return nil, err
}
return rp.MultiValue()
}
// Command send raw redis command to redis server
// and redis will return QUEUED back
func (t *Transaction) Command(args ...interface{}) error {
args2 := packArgs(args...)
if err := t.conn.SendCommand(args2...); err != nil {
return err
}
rp, err := t.conn.RecvReply()
if err != nil {
return err
}
s, err := rp.StatusValue()
if err != nil {
return err
}
if s != "QUEUED" {
return errors.New(s)
}
return nil
}