全网最全的Java SpringBoot点赞功能实现
Python实战量化交易理财系统
前言
下面贴下关键代码(项目使用了Mybatis-Plus):
看上去没什么问题,但是测试后数据却不正确,为什么呢?
CPU操作顺序:A线程查询 -> B线程查询 -> A线程保存 -> B线程保存
解决方案
青铜版
使用synchronized关键字锁住读写操作,操作完成后释放锁
这里要注意一点,使用String作为锁时一定要调用intern()方法,intern()会先从常量池中查找有没有相同的String,如果有就直接返回,没有的话会把当前String加入常量池,然后再返回。如果不调用这个方法锁会失效。
JMeter性能数据
优点:
-
保证了正确性
缺点:
-
性能太差,并发低的情况下还可以应付,并发高时用户体验极差
白银版
JMeter性能数据
优点:
-
性能比上一个方案好
缺点:
-
中规中矩,没什么大的缺点
黄金版
注意:Redis需要开启持久化,最好aof和rdb都开启,不然重启数据就丢失了
public boolean like(Integer userId, Integer productId) { List<String> keys = new ArrayList<>(); keys.add(buildUserRedisKey(userId)); keys.add(buildProductRedisKey(productId)); int value1 = 1; redisUtil.execute("lua-script/like.lua", keys, value1); return true; } private String buildUserRedisKey(Integer userId) { return "userId\_" + userId; } private String buildProductRedisKey(Integer productId) { return "productId\_" + productId; }
lua脚本
JMeter性能数据
优点:
-
性能非常好
缺点:
-
数据量多了内存占用较高
总结
如果对性能没有要求,可以使用白银版的实现方式,如果有要求,就使用黄金版的方式,内存占用大的问题也可以通过一些手段来解决,比如可以根据业务需求定期删除一些不常用的缓存数据,但是相对应的,查询的时候就需要在查询失败时再去查数据库。
源码
-
__EOF__