阅读 558

电商系统常见存储问题

如何避免重复下单

解决办法是,让你的订单服务具备幂等性。什么是幂等呢?一个幂等操作的特点是,其任意多次执行所产生的影响均与一次执行的影响相同。也就是说,一个幂等的方法,使用同样的参数,对它进行调用多次和调用一次,对系统产生的影响是一样的。

我们给订单系统增加一个“生成订单号”的服务,这个服务没有参数,返回值就是一个新的、全局唯一的订单号。在用户进入创建订单的页面时,前端页面先调用这个生成订单号服务得到一个订单号,在用户提交订单的时候,在创建订单的请求中带着这个订单号。

这个订单号也是我们订单表的主键,这样,无论是用户手抖,还是各种情况导致的重试,这些重复请求中带的都是同一个订单号。订单服务在订单表中插入数据的时候,执行的这些重复 INSERT 语句中的主键,也都是同一个订单号。数据库的唯一约束就可以保证,只有一次 INSERT 语句是执行成功的,这样就实现了创建订单服务幂等性。

如何解决 ABA 问题?

ABA 问题怎么解决?这里给你提供一个比较通用的解决方法。给你的订单主表增加一列,列名可以叫 version,也即是“版本号”的意思。每次查询订单的时候,版本号需要随着订单数据返回给页面。页面在更新数据的请求中,需要把这个版本号作为更新请求的参数,再带回给订单更新服务。

订单服务在更新数据的时候,需要比较订单当前数据的版本号,是否和消息中的版本号一致,如果不一致就拒绝更新数据。如果版本号一致,还需要再更新数据的同时,把版本号 +1。“比较版本号、更新数据和版本号 +1”,这个过程必须在同一个事务里面执行。

UPDATE orders set tracking_number = 666, version = version + 1WHERE version = 8;
复制代码

如何解决修改价格后用户页面的价格未变化

首先,商品系统需要保存包含价格的商品基本信息的历史数据,对每一次变更记录一个自增的版本号。在下单的请求中,不仅要带上SKUID,还要带上版本号。订单服务以请求中的商品版本对应的价格来创建订单,就可以避免“下单时突然变价”的问题了。

但是,这样改正之后会产生一个很严重的系统漏洞:黑客有可能会利用这个机制,以最便宜的历史价格来下单。所以,我们在下单之前需要增加一个检测逻辑:请求中的版本号只能是当前版本或者上一个版本,并且使用上一个版本要有一个时间限制,比如说调价5秒之后,就不再接受上一个版本的请求。这样就可以避免这个调价漏洞了。

数据库事务

如何用ES快速地实现搜索提示功能

因为用户每输入一个字都可能会发请求查询搜索框中的搜索推荐。所以搜索推荐的请求量远高于搜索框中的搜索。es针对这种情况提供了suggestion api,并提供的专门的数据结构应对搜索推荐,性能高于match,但它应用起来也有局限性,就是只能做前缀匹配。再结合pinyin分词器可以做到输入拼音字母就提示中文。如果想做非前缀匹配,可以考虑Ngram。不过Ngram有些复杂,需要开发者自定义分析器。比如有个网址www.geekbang.com,用户可能记不清具体网址了,只记得网址中有2个e,此时用户输入ee两个字母也是可以在搜索框提示出这个网址的。以上是我在工作中针对前缀搜索推荐和非前缀搜索推荐的实现方案。

mysql怎么能避免写出慢SQL

  • 使用索引避免全表扫描
  • 分析 SQL 执行计划

mysql如何应对高并发

  • 使用缓存
  • 读写分离