错题本

……尝试治一下自己的毛病

大致就是,写代码的时候做出许多假设,测试的时候发现假设并不总是成立。。

很多都是非常细小的问题,交付一个模块的时候记一下,不要再犯就是了

2019-11-14

微商城斑马二期用户分组、花型

  • MyBatis Plus默认不更新为null字段,导致无法将面料修改为花型

  • 重构商品校验Service时,取错集合,拼错字符串,导致花型无法设置为前10商品时报错文案错误

  • 商品占库业务没有考虑到库存可以为空,订单业务应该是花型订单才不占库,写反了

  • JRebel会导致修改Spring配置文件的配置项后不生效

  • 审核订单需要计算幅宽克重,没有跳过

  • 销售系统创建订单会根据类来推断订单类型,还有一个强行将生产数量置0的设定

  • 管理后端商品详情应该写sql 用嵌套查询查出子表内的完整记录,然后返回id和名称给前端

  • 商品详情没有返回折扣价,而且从登录Token信息取用户组id不一定是最新的

解决方案:

  • 单个用户认证并且变更所在用户组的时候,需要踢出该用户
  • 删除整个用户组时,需要踢出该用户组所有用户
  • 商品详情使用用户组id从数据库获取并返回当前用户的折扣信息,由前端计算实时的商品价格/价格配置价格
  • 订单详情的花型订单需要返回单品的单价
  • 商品列表也需要返回折扣

购物车展示折扣价

2019-9-16

从前往后

标签模块

  • 表名先用了复数,手写sql没改过来
  • 没考虑添加商品时没有带标签的情况
  • 删除接口Controller的请求方法写错
  • TagDTO用于传输公司id,使用BeanUtils.copy时将公司id复制过去,导致返回结果多出公司id来
  • 根据标签名搜索商品时 标签名与商品名条件应用OR排列,标签id应用and排列

2019-9-11

  • 商品列表我认为是空列表,但是没有再swagger里写清楚,前端不知是传空数组还是不传
    包括活动页Banner的必传性我也没有写清楚
    而我后台做了许多没有判null就进行的操作

  • 是否需要主标题为空的校验写错了类型,写到了个人中心页的Banner

  • 手动把模块表的某条记录从逻辑删除恢复,然后忘了恢复图片。。导致这个类型的模块拿不到,手动修了数据

  • 哎呦,吐了,设计出现重大问题
    之前做小程序banner一对多是按图片id做group,因为不想改原有数据结构
    现在出现问题了,用两张相同的图片发现商品id被group到一个图片里去了

得改改,用json字符串存这个图片-商品一对多好了

2019-08-28

Banner图模块

  • 关联查询时,由于习惯Mybatis Plus的自动过滤逻辑删除特性,自己撰写SQL时没有过滤关联查询表的已经逻辑删除的记录、以及子表中不存在的记录
    代码:
1
2
3
4
@Select("select m.id as module_id,m.is_required,m.title,m.subtitle,m.type,i.file_id,i.product_id,i.pno " +
"from wsc_pc_banner_module m left join wsc_pc_banner_image i on i.module_id = m.id " +
"${ew.customSqlSegment} and (i.is_deleted is NULL or i.is_deleted = 0) and m.is_deleted = 0 order by m.id")
List<WscPcBannerDO> selectBanner(@Param(Constants.WRAPPER) Wrapper wrapper);

重点在于and (i.is_deleted is NULL or i.is_deleted = 0)

  • 根据类型筛选Banner图,前端应该这么传值:
1
2
3
GET {{adminHost}}/microManage/pcBanner?type=0&type=3&type=4&type=5
Content-Type: application/json
Authorization: {{adminToken}}

后端应该这么接受:

1
2
3
4
@GetMapping("/pcBanner")
public JsonResult pcBanner(@RequestParam(required = false) Integer[] type) {
//...
}

前端直接用[0,3,4,5]这样的后端是接收不到的。。后端也不能用List来接受。。感觉这个设计有一点丑,但又不想额外写代码转换。。

记一次死锁

业务场景:微信支付模块,每一次请求都会在pay_log表里插入订单号等记录,支付回调时会更新pay_log表的记录

同时还有一个定时任务用来定时将所有1小时前的订单标记为交易超时

编写单元测试,模拟支付回调通知,结果出了异常,更新记录时出现死锁

大致SQL如下:

事务A

1
Update pay_log SET tradeState = 2 WHERE tradeState=0 AND createTime < '2019-08-20 15:23:04.167'

事务B

1
2
INSERT pay_log VALUES(NULL,?,NOW(),?,?,?,?,?,?,?,?,?,?,?,?) 
Update pay_log SET tradeState =? WHERE outTradeNo = ? AND tradeState = ? AND payType = ?

然后事务B被回滚了

解决方案:要么禁用定时任务,要么去掉单元测试的事务手动回滚,要么单元测试不要打断点调试(定时任务设置了项目启动后10秒后启动)

附上MySQL死锁日志,其实这玩意只能大致的定位故障,因为可以看出事务2的SQL只有最后执行的那一条

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2019-08-20 16:23:07 0x7ff1b2039700
*** (1) TRANSACTION:
TRANSACTION 43869195, ACTIVE 3 sec fetching rows
mysql tables in use 1, locked 1
LOCK WAIT 6 lock struct(s), heap size 1136, 269 row lock(s)
MySQL thread id 746830, OS thread handle 140676071700224, query id 184518127 192.168.3.108 root updating
Update pay_log SET tradeState = 2 WHERE tradeState=0 AND createTime < '2019-08-20 15:23:04.167'

*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 3179 page no 7 n bits 104 index PRIMARY of table `pay`.`pay_log` trx id 43869195 lock_mode X waiting
Record lock, heap no 37 PHYSICAL RECORD: n_fields 17; compact format; info bits 0


*** (2) TRANSACTION:
TRANSACTION 43869181, ACTIVE 7 sec starting index read
mysql tables in use 1, locked 1
4 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 2
MySQL thread id 747008, OS thread handle 140676050425600, query id 184518193 192.168.3.49 root updating
Update pay_log SET tradeState =1 WHERE outTradeNo = 'T9744695806' AND tradeState = 0 AND payType = 0

*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 3179 page no 7 n bits 104 index PRIMARY of table `pay`.`pay_log` trx id 43869181 lock_mode X locks rec but not gap
Record lock, heap no 37 PHYSICAL RECORD: n_fields 17; compact format; info bits 0

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 3179 page no 4 n bits 168 index PRIMARY of table `pay`.`pay_log` trx id 43869181 lock_mode X waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 17; compact format; info bits 0

*** WE ROLL BACK TRANSACTION (2)