你们是怎么使用 change data capture 来实现缓存失效的? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
请不要在回答技术问题时复制粘贴 AI 生成的内容
JasonLaw

你们是怎么使用 change data capture 来实现缓存失效的?

  •  
  •   JasonLaw Oct 23, 2020 1071 views
    This topic created in 2011 days ago, the information mentioned may be changed or developed.

    我先说一下我是怎么使用change data capture来实现缓存失效的。

    比如我有UserRepo,为了避免每次调用方法都要去查询数据库,我使用了@AutoCache实现了“有缓存直接取缓存;没缓存的话,查询数据库,然后缓存结果”。为了实现缓存失效,我使用了@AutoCacheInvalidation

    public interface UserMapper { // select * from user @AutoCache(timeToLiveInSecOnds= 60) // “将 primaryTable 设为"user"”代表“只要 user 表有变化,Redis 中的 key UserMapper.findAll()需要被清除” @AutoCacheInvalidation(primaryTable = "user", primaryTableColumns = {}, joinTables = {}, joinTableColumns = {}) List<Object> findAll(); // select * from user where id = #{id} @AutoCache(timeToLiveInSecOnds= 60) // “将 primaryTable 设为"user",primaryTableColumns 设为{"id"}”代表“如果 id 为 1 的 user 有变化,Redis 中的 key UserMapper.findById(1)需要被清除” @AutoCacheInvalidation(primaryTable = "user", primaryTableColumns = {"id"}, joinTables = {}, joinTableColumns = {}) Object findById(int id); // select * from user where name = #{name} and age = #{age} @AutoCache(timeToLiveInSecOnds= 60) // “将 primaryTable 设为"user",primaryTableColumns 设为{"name", "age"}”代表“如果 name 为 jason 、age 为 18 的 user 有变化,Redis 中的 key UserMapper.findByNameAndAge(jason, 18)需要被清除” @AutoCacheInvalidation(primaryTable = "user", primaryTableColumns = {"name", "age"}, joinTables = {}, joinTableColumns = {}) List<Object> findByNameAndAge(String name, int age); } 

    缓存失效服务会收集@AutoCacheInvalidation。缓存失效服务通过 change data capture 了解数据库的变化,然后清除相应的 Redis keys 。


    想问一下大家是怎么使用 change data capture 来实现缓存失效的,或者针对我现在的实现,给点建议,谢谢。

    我会在附言中说明我是怎么处理类似select * from user u join city c on u.city_id = c.id where u.id = 1这样的语句的,以及怎么处理“方法存在非数据库字段的参数”的(比如UserPostMapper.pageUserPosts(int userId, int offset, int limit))。

    Supplement 1    Oct 23, 2020

    处理类似select * from user u join city c on u.city_id = c.id where u.id = 1这样的语句时,我会利用到joinTablesjoinTableColumns,如下所示:

    public interface UserMapper { // select * from user u join city c on u.city_id = c.id where u.id = #{id} @AutoCache(timeToLiveInSecOnds= 60) @AutoCacheInvalidation(primaryTable = "user", primaryTableColumns = {"id"}, joinTables = {"city"}, joinTableColumns = {"id"}) // “将primaryTable设为"user",primaryTableColumns设为{"id"}”代表“如果id为1的user有变化,Redis中的key UserMapper.findUserDetail(1)需要被清除” // “将joinTables设为{"city"},joinTableColumns设为{"id"}”代表"如果id为1的city有变化,Redis中的key UserMapper.findUserDetail(?)需要被清除",但是?代表什么呢? // id为1的city有变化,那么跟id为1的city有关联的用户都会受到影响,所以我使用了select id from user where city_id = 1来确定受影响的用户。 // 假设select id from user where city_id = 1的结果为[1, 2, 3],那么Redis中的keys UserMapper.findUserDetail(1)、UserMapper.findUserDetail(2)、UserMapper.findUserDetail(3)都会被清除。 Object findUserDetail(String id); } 
    Supplement 2    Oct 23, 2020

    如果方法存在非数据库字段的参数时,我会利用到@NonTableColumn

    当方法存在非数据库字段的参数时,比如UserPostMapper.pageUserPosts(int userId, int offset, int limit),需要给offsetlimit加上@NonTableColumn

    这个时候会使用Redis Hashes缓存结果,而不是Strings。如果方法被调用时,userId1offset0limit5,那么key就是UserPostMapper.pageUserPosts(1, ?, ?),field为0, 5,value为postList

    UserPostMapper.pageUserPosts(int userId, @NonTableColumn int offset, @NonTableColumn int limit)对应的@AutoCacheInvalidation@AutoCacheInvalidation(primaryTable = "user_post", primaryTableColumns = {"user_id"}, joinTables = {}, joinTableColumns = {}),代表如果user_id1user_post有变化,Reds中的key UserPostMapper.pageUserPosts(1, ?, ?)会被删除。

    No Comments Yet
    About     Help     Advertise     Blog     API     FAQ     Solana     5615 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 41ms UTC 08:47 PVG 16:47 LAX 01:47 JFK 04:47
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86