...

Source file src/github.com/redis/go-redis/v9/doctests/pipe_trans_example_test.go

Documentation: github.com/redis/go-redis/v9/doctests

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

View as plain text