redis和mysql事务一致性_spring数据库事务和基于redisson的redis缓存事务结合使用保持数据一致性...

redis和mysql事务一致性_spring数据库事务和基于redisson的redis缓存事务结合使用保持数据一致性..._第1张图片

有时候我们在操作数据的时候会更改多张表的数据,我们往往期望的结果是要么都修改成功,要么都修改失败。这个时候就会使用数据库事务,spring/spring boot框架对事务有较好的支持。随着业务的不断拓展、用户量、数据量不断的扩张,网站总会遇上性能问题,这个时候缓存就上场了。redis是不错的缓存组件,无论你的架构是简单的存储还是需要高可用甚至是数据分片集群,redis都能很好的满足你的需求。

通常使用缓存,是提不到事务的高度的,毕竟缓存有的数据,数据库都有,reload一下就可以了。但是有的业务场景对缓存的要求可能就会更高了,比如促销、活动规则等的一些缓存,这些缓存访问频度非常高,缓存的重要程度在一些系统架构设计中甚至高过了数据库。

在一些缓存和数据库同时使用的业务系统中,有时候我们希望更新数据库的数据同时能够更新缓存的数据。但是这是两个不同的数据源,有时候数据库更新成功了,缓存却更新失败,而对于时间敏感的客户端请求通常是直接访问缓存的,这样一来,缓存和数据库数据不一致性导致的错误可能是比较严重的。

幸运的时,我们现在可以找到不错的解决方案。redis是支持事务的,相关命令可参考:

springboot或spring中使用编程式事务和声明式事务都能很好的支持数据库事务。声明式事务使我们推荐的,如果我们要结合redis事务和spring事务,我们该如何处理呢?我们以比较不错的的开源组件redisson为例来说一下。

思路是这样的,我们通常在修改数据库后会更新缓存,我们再这个修改数据库的事务中内嵌一个redis事务,如下:

上面的代码中,saveToDb使用的是数据库事务,saveToCache使用的是redis事务。注解@Transactional声明了整个方法transactionalDemo是一个事务。由于spring声明式事务包裹了redis的事务,spring声明式事务在我们现有的系统仅针对数据库事务有效,所以只要saveToCache方法执行抛出异常,那么数据库事务也会回滚(rollback)。

redis事务使用很简单,可以参考上文提到的命令,我们使用了redisson,redisson也对redis事务做了一定的支持,虽然功能还不是很多,但足够我们使用。使用redisson创建事务非常简单:

如果你在commit之前有抛出异常,或者超时未提交事务,所有的redis指令都不会执行,同时还会抛出异常,外层的事务捕捉到后也不会执行数据库的任何写操作。

为了对redis的操作简单,你甚至可以简单封装一下redisson相关的api,如下是部分代码,主要针对Set(集合)和桶(Redis中的String),其他的可根据需要自行完善:

要使用上面的Transaction类,非常简单,如下:

redis的事务是编程式事务,如果你感兴趣,也可以使用spring AOP的方式实现自定义注解,这样你也可以在你的缓存操作上加上类似@Transactional的注解实现声明式事务啦。通过spring和springboot框架,有了数据库事务和redis事务的结合,我们能够最大限度的保证在修改数据库的同时也修改了缓存数据,极大限度的保证了缓存和数据库的数据一致性。

你可能感兴趣的:(redis和mysql事务一致性_spring数据库事务和基于redisson的redis缓存事务结合使用保持数据一致性...)