Redis:对比一下Redis和MySQL的事务

QAQ。。水稻前两天研究完MySQL的事务,今天看到了Redis,也产生了兴趣。准备下手看看

小白:水稻哥,你在看啥呢,这么专注

水稻:在看Redis的事务,有点收获

小白:真的吗?科普一下呗!

水稻:嗯,从与MySQL的不同点开始说,Redis的事务不支持事务的原子性,事务内的一组操作并不支持异常回滚。这里分为两种情况

  • 语法异常:类比java编译时异常,事务中出现语法错误,譬如set误写成sett等。在提交的时候就能检查出来,整个事务都不会执行
  • 业务异常:类比java的运行时异常,譬如将list的命令操作在string上。命令提交的时候检测不出来,可以正常提交,错误的命令不能执行,其他的命令正常执行,不会回滚

小白:Redis为什么这么豪横

水稻:搜索官方文档可以发现

  • 根本原因可能还是Redis的定位是缓存。不加入回滚逻辑可以使它简洁,快速
  • 官方解释是:运行时的异常不应该发生在生产环境,就是Redis不应为程序员的bug买单
  • Redis可以以脚本的形式支持事务的执行。历史原因,先出现了事务,后出现的脚本。暂时不打算撤销事务的功能,它提供了无脚本也能支持简单事务的功能,但是如果随着后续脚本方案的流行可能会在后续版本移除事务功能

小白:厉害了。我还听说过Discard和Watch命令?能说说吗

水稻:

  • Discard支持在事务内部主动撤销事务,该命令会清空事务队列。
  • Watch命令则是提供一种CAS乐观锁的机制,可以变相的支持事务的隔离性,可以事先监听关注的key,其他事务如果在当前事务执行前修改了监听的key,那么当前事务就会被取消。程序要做的就是监听到失败的结果,然后进行重试。
    • 举个栗子??
    • 第一个客户端 开启事务multi get k1 ,set k2 aaa 
    • 第二个客户端 开启事务multi del k1 , exec  
    • 第一个客户端 提交事务exec , 会发现k2是可以set成功的
    • 如果在第一个客户端开启事务之前监听k1的变化,那么k2是会set失败的

小白:懂了!!懂了

水稻:相互学习!!!  

  

相关推荐