redis有5个命令可以让用户在不被打断的情况下对多个键执行操作,分别是watch,multi,exec,unwatch,discard。
本文只介绍multi和exec命令。
什么是redis的基本事物
redis的基本事物需要用到multi和exec,这个命令可以让一个客户端在不被其他客户端打扰的情况下执行多个命令。和关系型数据库那种可以在事务中回滚不同,在redis中,被multi和exec包裹的命令会一个接一个的执行,直到所有的完成。
为了演示事物,最好还是用某种编程语言来演示多线程,这样结果会因为没有事物而发生出乎意料的结果。
代码示例
没有事物
import threading
import time
import redis
conn = redis.Redis(host='localhost', port=6379, db=0)
def notrans():
print(conn.incr('notrans:'))
time.sleep(.1)
conn.incr('notrans:',-1)
if 1:
for i in range(3):
threading.Thread(target=notrans).start()
time.sleep(.5)
在这段代码里,对同一个string先自增,然后打印出来,在自减。我们希望看到的是每次打印的都是1,但是,多个线程同时运行,结果就不是我们期望的那样了。
结果:
/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7 /Users/dubby/Desktop/Lab/PyRedis/noTrans.py
1
2
3
Process finished with exit code 0
有事物
import threading
import time
import redis
conn = redis.Redis(host='localhost', port=6379, db=0)
def trans():
pipeline = conn.pipeline()
pipeline.incr('trans:')
time.sleep(.1)
pipeline.incr('trans:',-1)
print(pipeline.execute()[0])
if 1:
for i in range(3):
threading.Thread(target=trans).start()
time.sleep(.5)
结果:
/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7 /Users/dubby/Desktop/Lab/PyRedis/trans.py
111
Process finished with exit code 0
在python客户端中,事物是由流水线(pipeline)实现的:对连接对象调用pipeline()将创建一个事物,在一切正常的情况下,客户端会自动使用multi和exec包裹用户输入的多个命令。此外,为了减少redis和客户端的通信往返次数,提升执行多个命令时的性能,python的redis客户端会存储事物包含的多个命令,然后在执行时一次性的将所有命令全部发送给redis。