Redis之坑:Redis与MySQL中事务的区别

Note:java

  1. 该篇讨论的只是Redis与MySQL中事务的区别,并不能统一表明NO-SQL与关系型SQL;
  2. 在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务;

事务命令

MySQL:redis

  • BEGIN:显式地开启一个事务;
  • COMMIT:提交事务,将对数据库进行的全部修改变成为永久性的;
  • ROLLBACK:结束用户的事务,并撤销正在进行的全部未提交的修改;

Redis:spring

  • MULTI:标记事务的开始;
  • EXEC:执行事务的commands队列;
  • DISCARD:结束事务,并清除commands队列;

Redis之坑:理解Redis事务 中咱们经过类比MySQL的BEGAIN,COMMIT,ROLLBACK来理解Redis的事务命令。可是显然,它们有着本质区别。数据库


默认状态

MySQL:bash

  • MySQL会默认开启一个事务,且缺省设置是自动提交,即,每成功执行一个SQL,一个事务就会立刻 COMMIT。因此不能Rollback。

Redis:app


使用方式

MySQL: 包含两种spa

  1. 用 BEGIN, ROLLBACK, COMMIT,显式开启并控制一个 新的 Transaction。
  2. 执行命令SET AUTOCOMMIT=0,用来禁止当前会话自动commit,控制默认开启的事务

Redis:.net

  1. 用 MULTI, EXEC, DISCARD,显式开启并控制一个Transaction(注意:这里没有强调 “新的” ,由于默认是不会开启事务的)。

实现原理

很容易理解,Redis与MySQL中事务的区别其根本缘由就是实现不一样方式形成的。日志

MySQL:code

  • MySQL实现事务,是基于UNDO/REDO日志
  • UNDO日志记录修改前状态,ROLLBACK基于UNDO日志实现;
  • REDO日志记录修改后的状态 ,COMMIT基于REDO日志实现;
  • 在MySQL中不管是否开启事务,SQL都会被当即执行并返回执行结果。只是**事务开启**后执行后的状态只是记录在REDO日志,执行COMMIT以后,数据才会被写入磁盘
int insertSelective = serviceOrderMapper.insertSelective(s);
复制代码

因此,上述代码,insertSelective 将会被当即赋值(不管是否开启事务,只是结果或未被写入磁盘):

insertSelective = 受影响的行数;
复制代码

Redis:

  • Redis实现事务,是基于COMMANDS队列
  • 若是没有开启事务,command将会被当即执行并返回执行结果,而且直接写入磁盘;
  • 若是事务开启,command不会被当即执行,而是排入队列并返回排队状态(具体依赖于客户端(例如:spring-data-redis)自身实现)。调用EXCE才会执行COMMANDS队列
boolean a = redisTemplate.opsForZSet().add("generalService",orderId,System.currentTimeMillis());
复制代码

上述代码,

  • 若是没有开启事务,操做被当即执行,a 将会被当即赋值(true|false);
  • 若是开启事务,操做未被当即之行,将会返回NULL值,而a的类型是boolean,因此将会抛出异常: java.lang.NullPointerException
相关文章
相关标签/搜索