1
0
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:
Vladimir Mihailenco
2016-05-02 15:54:15 +03:00
parent 033a4de2fb
commit 092698ecd3
8 changed files with 138 additions and 161 deletions

View File

@ -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())
})
})