<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[fal1230的博客]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/fal1230</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; fal1230]]></copyright><item><title><![CDATA[Spring事物注解@Transactional与代码锁冲突原因分析]]></title><link>https://blog.youkuaiyun.com/fal1230/article/details/113392123</link><guid>https://blog.youkuaiyun.com/fal1230/article/details/113392123</guid><author>fal1230</author><pubDate>Tue, 09 Feb 2021 15:01:21 +0800</pubDate><description><![CDATA[业务场景如下：

用户频繁(疯狂)点击送礼物按钮给主播刷礼物

代码实现业务步骤：

1.查询礼物金额

2.查询用户钱包金额

3.查询钱包余额是否充足

4.用户钱包减去礼物金额

5.主播钱包增加礼物金额

代码方案：

1.因为涉及金额问题，且操作中需要对用户和主播的钱包都进行相应操作，所以需要使用@Transactional事物注解。

2.因用户频繁点击场景，为了防止用户钱包余额校验等金额问题出现异常，需要使用分布式锁或synchronized单机锁进行安全处理。

为什么要设计的这么严格：如果]]></description><category></category></item><item><title><![CDATA[提升工作幸福指数工具类 实用redisKey管理工具类]]></title><link>https://blog.youkuaiyun.com/fal1230/article/details/111593941</link><guid>https://blog.youkuaiyun.com/fal1230/article/details/111593941</guid><author>fal1230</author><pubDate>Wed, 23 Dec 2020 17:18:11 +0800</pubDate><description><![CDATA[问题：实际工作中经常遇到要使用redis配合的业务场景，那么就避免不了定义redis的key，在实际业务中为了区分key经常需要对key进行业务拼接，如 user:info:id:123 。

遇到上述情况常规方案 伪代码如下：


// 定义常量redisKey
public static final String USER_INFO_ID= "user:info:id:";
// 将常量与变量拼接
String redisKey =USER_INFO_ID+"123";
// 使用拼接好的redis..]]></description><category></category></item><item><title><![CDATA[微信高并发下红包功能实战JAVA版(一)整体实现思路]]></title><link>https://blog.youkuaiyun.com/fal1230/article/details/109060520</link><guid>https://blog.youkuaiyun.com/fal1230/article/details/109060520</guid><author>fal1230</author><pubDate>Tue, 13 Oct 2020 21:42:51 +0800</pubDate><description><![CDATA[逛知乎时偶然发现一篇微信红包的实战案例，阅读之后对文章的实现思路有些自己的看法，所以分享给各位小伙伴。

1.业务流程

相信大家都使用过微信抢红包功能，业务流程如下：

1.土豪发红包:

 a.设置红包金额

 b.设置红包数量

2.我们去抢土豪发出的红包

 a.手快-获得随机金额红包

 b.手慢-红包被抢完

这里有几个隐藏的逻辑：

1.土豪发红包时，设置的金额与数量是有最小金额限制的------单个红包金额不可低于0.01元



2.抢红包时，如果红包数大于1，即使最后一个...]]></description><category></category></item><item><title><![CDATA[Java实现 接口请求频率限制方案源码]]></title><link>https://blog.youkuaiyun.com/fal1230/article/details/108607491</link><guid>https://blog.youkuaiyun.com/fal1230/article/details/108607491</guid><author>fal1230</author><pubDate>Tue, 15 Sep 2020 20:26:19 +0800</pubDate><description><![CDATA[实际工作中在某些业务场景会遇到一个问题，用户疯狂点击某个按钮功能导致接口在短时间内被重复请求多次，且这些重复请求在业务上是无效的请求，这个问题即会导致后端出现大量重复无效或错误的数据，也会对后端服务器等造成影响。

解决方案需要从服务端的部署方式出发

1.集群部署(如果nginx等转发服务器采用按IP或SESSION_ID等方式的转发策略也可使用单机部署的方案)：集群部署的情况推荐使用redis分布式锁进行处理，具体代码方案参考之前的文章：

Java+RedisTemplate 实现redis分布式锁
]]></description><category></category></item><item><title><![CDATA[Java+RedisTemplate 实现redis分布式锁]]></title><link>https://blog.youkuaiyun.com/fal1230/article/details/106429851</link><guid>https://blog.youkuaiyun.com/fal1230/article/details/106429851</guid><author>fal1230</author><pubDate>Fri, 29 May 2020 17:35:52 +0800</pubDate><description><![CDATA[api demo:

set("key","value",30, TimeUnit.SECONDS);

redisTemplate demo:

redisTemplate.opsForValue().setIfAbsent("onlykey","value",10, TimeUnit.SECONDS);



setnx大致原理，主要依托了它的key不存在才能set成功的特性，进程A拿到锁，在没有删除锁的Key时，进程B自然获取锁就失败了。



使用redisTemplate setIfAb...]]></description><category></category></item><item><title><![CDATA[split字符串拆分踩坑记录(字符串拆分后数组下标越界解决方案)]]></title><link>https://blog.youkuaiyun.com/fal1230/article/details/106355958</link><guid>https://blog.youkuaiyun.com/fal1230/article/details/106355958</guid><author>fal1230</author><pubDate>Tue, 26 May 2020 14:43:25 +0800</pubDate><description><![CDATA[问题：使用split拆分String字符串后拿到的数组发现一个问题-如果拆分的字符串根据拆分规则拆分后，后面的未知上如果没有值，则split返回的数组会自动忽略它们。

demo：代码第四行返回的数组长度是4，如果是批量处理String操作，使用array[4]时就会报错下标越界问题


String temp = "1,2,3,4,5";
System.out.println(temp.split(",").length); //5
temp = "1,2,3,4,";
System.out.printl]]></description><category></category></item><item><title><![CDATA[提升工作幸福指数工具类 适合绝大部分代码场景：判断是否为空/不为空]]></title><link>https://blog.youkuaiyun.com/fal1230/article/details/105093511</link><guid>https://blog.youkuaiyun.com/fal1230/article/details/105093511</guid><author>fal1230</author><pubDate>Wed, 25 Mar 2020 14:54:42 +0800</pubDate><description><![CDATA[Optional对象

Optional是Java8新加入的一个容器，这个容器只存1个或0个元素，它用于防止出现NullpointException，它提供如下方法：

isPresent()
判断容器中是否有值。（使用频率最高）

ifPresent(Consume lambda)
容器若不为空则执行括号中的Lambda表达式。

T get()
获取容器中的元素，若容器为空则抛出NoSuchE...]]></description><category></category></item><item><title><![CDATA[@Scheduled 定时任务总结]]></title><link>https://blog.youkuaiyun.com/fal1230/article/details/81237689</link><guid>https://blog.youkuaiyun.com/fal1230/article/details/81237689</guid><author>fal1230</author><pubDate>Fri, 27 Jul 2018 15:22:13 +0800</pubDate><description><![CDATA[@Scheduled

作用：spring定时器(定时执行一次或定时轮询执行一段代码)

使用场景：注解在方法上

参数说明：常用参数

@Scheduled 参数说明

String cron:cron表达式定义了方法执行的时间规则(网上对这个的说明很多就不墨迹了)

生成器工具地址-http://cron.qqe2.com/

Long fixedDelay：定时任务每隔多久执行一次，单位是毫...]]></description><category></category></item></channel></rss>