Redis 事务的本质是一组命令的集合。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。
总结说: redis事务就是一次性、顺序性、排他性的执行一个队列中的一系列命令。 在简单点的意思就是Redis只能保证一个client发起的事务中的命令可以连续的执行,而中间不会插入其他client的命令
因为redis是单线程,所有命令会先放入一个缓存队列中然后等待exec命令,如果使用了exec命令,那么这一批命令会直接插入到执行队列中,在插入的过程中,会阻塞其他客户端插入命令,那么我们就能保证这一组命令的执行过程中不会有其他任何命令在执行,也就能保证在这一组命令执行的过程中数据的安全性(隔离性)
Redis中,单条命令是原子性执行的,但事务不保证原子性,且没有回滚。事务中任意命令执行失败,其余的命令仍会被执行。
若在事务队列中存在命令性错误(类似于java编译性错误),则执行EXEC命令时,所有命令都不会执行
事务块中某条语句存在语法性错误(类似于java的1/0的运行时异常),则执行EXEC命令时,其他正确命令会被执行,错误命令会抛出异常。
Redis不支持事务的回滚机制,即使事务队列中的某个命令在执行期间出现错误,整个事务也会继续执行下去,直到将事务队列中的所有命令都执行完毕为止
Redis的作者在事务功能的文档中解释说,不支持事务回滚是因为这种复杂的功能和Redis追求的简单高效的设计主旨不符合,并且他认为,Redis事务的执行时,错误通常都是编程错误造成的,这种错误通常只会出现在开发环境中,而很少会在实际的生产环境中出现,所以他认为没有必要为Redis开发事务回滚功能。所以我们在讨论Redis事务回滚的时候,一定要区分命令发生错误的时候。
何时取消 key 的监视(WATCH)?
①WATCH 命令可以被调用多次。对键的监视从 WATCH 执行之后开始生效,直到调用 EXEC 为止。不管事务是否成功执行,对所有键的监视都会被取消。
②当客户端断开连接时,该客户端对键的监视也会被取消。
③UNWATCH 命令可以手动取消对所有键的监视
最简单的事物案例
注意: 事物内所有命令的结果最后都会在exec执行后返回
假设买票案例,当前只有1张票和100块钱,如果我在买票的过程中,在我multi之后,和exec之前,票被别人买了—即ticket已经变成0了,然后我们执行exec的时候就会将票变为-1,这就不对了。
在执行我们说了multi 只是定义一组事物的开始,之后需要执行的命令是会被放入到缓存队列中,那么在期间主队列的其他客户端命令是不会收到影响的,直到你执行了exec之后才轮到你执行命令
multi
exec
在举一个案例:
1) 在 A 客户端设置 key : strlp 登录人数为 10
2) 在 A 客户端监视 key : strlp
3) 在 A 客户端开启事务 multi
4) 在 A 客户端修改 strlp 的值为 11
5) 此刻A 客户还没执行exec前 B 客户端修改 strlp 的值为 15
6) A 客户端执行事务 exec ,因为WATCH发现strlp的值已经被修改了,所有放弃事务。