mirror of
https://github.com/redis/go-redis.git
synced 2025-07-28 06:42:00 +03:00
Tweak transaction API.
This commit is contained in:
147
tx_test.go
147
tx_test.go
@ -27,21 +27,18 @@ var _ = Describe("Tx", func() {
|
||||
|
||||
// Transactionally increments key using GET and SET commands.
|
||||
incr = func(key string) error {
|
||||
tx, err := client.Watch(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Close()
|
||||
err := client.Watch(func(tx *redis.Tx) error {
|
||||
n, err := tx.Get(key).Int64()
|
||||
if err != nil && err != redis.Nil {
|
||||
return err
|
||||
}
|
||||
|
||||
n, err := tx.Get(key).Int64()
|
||||
if err != nil && err != redis.Nil {
|
||||
_, err = tx.MultiExec(func() error {
|
||||
tx.Set(key, strconv.FormatInt(n+1, 10), 0)
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.Exec(func() error {
|
||||
tx.Set(key, strconv.FormatInt(n+1, 10), 0)
|
||||
return nil
|
||||
})
|
||||
}, key)
|
||||
if err == redis.TxFailedErr {
|
||||
return incr(key)
|
||||
}
|
||||
@ -67,20 +64,18 @@ var _ = Describe("Tx", func() {
|
||||
})
|
||||
|
||||
It("should discard", func() {
|
||||
tx, err := client.Watch("key1", "key2")
|
||||
err := client.Watch(func(tx *redis.Tx) error {
|
||||
cmds, err := tx.MultiExec(func() error {
|
||||
tx.Set("key1", "hello1", 0)
|
||||
tx.Discard()
|
||||
tx.Set("key2", "hello2", 0)
|
||||
return nil
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(cmds).To(HaveLen(1))
|
||||
return err
|
||||
}, "key1", "key2")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
defer func() {
|
||||
Expect(tx.Close()).NotTo(HaveOccurred())
|
||||
}()
|
||||
|
||||
cmds, err := tx.Exec(func() error {
|
||||
tx.Set("key1", "hello1", 0)
|
||||
tx.Discard()
|
||||
tx.Set("key2", "hello2", 0)
|
||||
return nil
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(cmds).To(HaveLen(1))
|
||||
|
||||
get := client.Get("key1")
|
||||
Expect(get.Err()).To(Equal(redis.Nil))
|
||||
@ -92,43 +87,41 @@ var _ = Describe("Tx", func() {
|
||||
})
|
||||
|
||||
It("should exec empty", func() {
|
||||
tx, err := client.Watch()
|
||||
err := client.Watch(func(tx *redis.Tx) error {
|
||||
cmds, err := tx.MultiExec(func() error { return nil })
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(cmds).To(HaveLen(0))
|
||||
return err
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
defer func() {
|
||||
Expect(tx.Close()).NotTo(HaveOccurred())
|
||||
}()
|
||||
|
||||
cmds, err := tx.Exec(func() error { return nil })
|
||||
v, err := client.Ping().Result()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(cmds).To(HaveLen(0))
|
||||
|
||||
ping := tx.Ping()
|
||||
Expect(ping.Err()).NotTo(HaveOccurred())
|
||||
Expect(ping.Val()).To(Equal("PONG"))
|
||||
Expect(v).To(Equal("PONG"))
|
||||
})
|
||||
|
||||
It("should exec bulks", func() {
|
||||
tx, err := client.Watch()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
defer func() {
|
||||
Expect(tx.Close()).NotTo(HaveOccurred())
|
||||
}()
|
||||
const N = 20000
|
||||
|
||||
cmds, err := tx.Exec(func() error {
|
||||
for i := int64(0); i < 20000; i++ {
|
||||
tx.Incr("key")
|
||||
err := client.Watch(func(tx *redis.Tx) error {
|
||||
cmds, err := tx.MultiExec(func() error {
|
||||
for i := 0; i < N; i++ {
|
||||
tx.Incr("key")
|
||||
}
|
||||
return nil
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(len(cmds)).To(Equal(N))
|
||||
for _, cmd := range cmds {
|
||||
Expect(cmd.Err()).NotTo(HaveOccurred())
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(len(cmds)).To(Equal(20000))
|
||||
for _, cmd := range cmds {
|
||||
Expect(cmd.Err()).NotTo(HaveOccurred())
|
||||
}
|
||||
|
||||
get := client.Get("key")
|
||||
Expect(get.Err()).NotTo(HaveOccurred())
|
||||
Expect(get.Val()).To(Equal("20000"))
|
||||
num, err := client.Get("key").Int64()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(num).To(Equal(int64(N)))
|
||||
})
|
||||
|
||||
It("should recover from bad connection", func() {
|
||||
@ -140,22 +133,21 @@ var _ = Describe("Tx", func() {
|
||||
err = client.Pool().Put(cn)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
tx, err := client.Watch()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
defer func() {
|
||||
Expect(tx.Close()).NotTo(HaveOccurred())
|
||||
}()
|
||||
do := func() error {
|
||||
err := client.Watch(func(tx *redis.Tx) error {
|
||||
_, err := tx.MultiExec(func() error {
|
||||
tx.Ping()
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.Exec(func() error {
|
||||
tx.Ping()
|
||||
return nil
|
||||
})
|
||||
err = do()
|
||||
Expect(err).To(MatchError("bad connection"))
|
||||
|
||||
_, err = tx.Exec(func() error {
|
||||
tx.Ping()
|
||||
return nil
|
||||
})
|
||||
err = do()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
@ -168,21 +160,20 @@ var _ = Describe("Tx", func() {
|
||||
err = client.Pool().Put(cn)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
{
|
||||
tx, err := client.Watch("key")
|
||||
Expect(err).To(MatchError("bad connection"))
|
||||
Expect(tx).To(BeNil())
|
||||
do := func() error {
|
||||
err := client.Watch(func(tx *redis.Tx) error {
|
||||
_, err := tx.MultiExec(func() error {
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
}, "key")
|
||||
return err
|
||||
}
|
||||
|
||||
{
|
||||
tx, err := client.Watch("key")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
err = do()
|
||||
Expect(err).To(MatchError("bad connection"))
|
||||
|
||||
err = tx.Ping().Err()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = tx.Close()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
err = do()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
})
|
||||
|
Reference in New Issue
Block a user