显然这样存在「并发问题」,正例应该「利用数据库删除操作的原子性」,如下:
if(deleteAvailableTicketById(ticketId) == 1){
1、给现金增加操作
}else{
return “没有可用现金券”
}
因此,这个习惯也是要有的,「写完代码,自己想下多线程执行,是否会存在并发一致性问题」。
9.对象获取属性,先判断对象是否为空
这个点本来也属于「采取措施规避运行时异常」的,但是我还是把它拿出来,当做一个重点来写,因为平时空指针异常太常见了,一个手抖不注意,就导致空指针报到生产环境去了。
所以,你要获取对象的属性时,尽量不要相信「理论上不为空」,我们顺手养成习惯判断一下是否为空,再获取对象的属性。正例:
if(object!=null){
String name = object.getName();
}
10.多线程异步优先考虑恰当的线程池,而不是new thread,同时考虑线程池是否隔离
为什么优先使用线程池?使用线程池有这几点好处呀
同时呢,尽量不要所有业务都共用一个线程池,需要考虑「线程池隔离」。就是不同的关键业务,分配不同的线程池,然后线程池参数也要考虑恰当哈。之前写过几篇线程池的,觉得还不错,有兴趣的朋友可以看一下哈
11. 手动写完代码业务的SQL,先拿去数据库跑一下,同时也explain看下执行计划。
手动写完业务代码的SQL,可以先把它拿到数据库跑一下,看看有没有语法错误嘛。有些小伙伴不好的习惯就是,写完就把代码打包上去测试服务器,其实把SQL放到数据库执行一下,可以规避很多错误的。
同时呢,也用「explain看下你Sql的执行计划」,尤其走不走索引这一块。
explain select * from user where userid =10086 or age =18;
12.调用第三方接口,需要考虑异常处理,安全性,超时重试这几个点。
调用第三方服务,或者分布式远程服务的的话,需要考虑
如果是转账等重要的第三方服务,还需要考虑「签名验签」,「加密」等。之前写过一篇加签验签的,有兴趣的朋友可以看一下哈
13.接口需要考虑幂等性
接口是需要考虑幂等性的,尤其抢红包、转账这些重要接口。最直观的业务场景,就是「用户连着点两次」,你的接口有没有hold住。
一般「幂等技术方案」有这几种:
14. 多线程情况下,考虑线性安全问题
在「高并发」情况下,HashMap可能会出现死循环。因为它是非线性安全的,可以考虑使用ConcurrentHashMap。所以这个也尽量养成习惯,不要上来反手就是一个new HashMap();
15.主从延迟问题考虑
先插入,接着就去查询,这类代码逻辑比较常见,这「可能」会有问题的。一般数据库都是有主库,从库的。写入的话是写主库,读一般是读从库。如果发生主从延迟,,很可能出现你插入成功了,但是你查询不到的情况。
16.使用缓存的时候,考虑跟DB的一致性,还有(缓存穿透、缓存雪崩和缓存击穿)
通俗点说,我们使用缓存就是为了「查得快,接口耗时小」。但是呢,用到缓存,就需要「注意缓存与数据库的一致性」问题。同时,还需要规避缓存穿透、缓存雪崩和缓存击穿三大问题。
个人公众号
感兴趣的朋友,可以关注我公众号哈