合规国际互联网加速 OSASE为企业客户提供高速稳定SD-WAN国际加速解决方案。 广告
## 生成唯一订单号 确保生产唯一的订单号,字段建立唯一索引。 * * * * * ### 一般方案 ```php for ($i = 0; $i < $data['createnum']; $i++) { do { // $code = strtolower(get_rand_str(8, 0, 1)); // 获取随机8位字符串 // 零填充导致Excel显示数字不正确 $code = zerofill(mt_rand(0, 99999999), 8, 9); $password = mt_rand(1000, 9999); // 获取随机4位数字 $check_exist = M('exchange_list')->where(array('code' => $code))->find(); } while ($check_exist); $add['code'] = $code; $add['password'] = $password; $newId = M('exchange_list')->add($add); if (!$newId) { exit('重复!'); } else { } } ``` https://coding.net/u/xiasf/p/gj-shop/git/blob/master/Application/Admin/Controller/ExchangeController.class.php 这里只知道插入失败就表示重复,其实这是不准确的,有可能是别的原因导致插入失败呢,不一定是重复原因,除非能得到sql失败的错误码,每种情况都有一个系统确定的错误码,比如重复有一个错误码。 重复不能失败,而是要重试。 * * * * * ### 终极方案 ```php /* 插入订单表 */ $error_no = 0; do { $order['order_sn'] = get_order_sn(); //获取新订单号 $GLOBALS['db']->autoExecute($GLOBALS['ecs']->table('order_info'), $order, 'INSERT'); $error_no = $GLOBALS['db']->errno(); if ($error_no > 0 && $error_no != 1062) { die($GLOBALS['db']->errorMsg()); } } while ($error_no == 1062); //如果是订单号重复则重新提交数据 $new_order_id = $db->insert_id(); $order['order_id'] = $new_order_id; ``` 这里更加完善就是能够识别到重复插入(唯一索引限制)报错的错误码:1062 不过这个错误码可能每个数据库系统都不一样。 这种方式应该是最完美安全的终极方案了。 [电商网站订单号怎么生成呢?我目前用订单ID来做感觉不行,从1开始这样太不好看了,像淘宝那样的订单ID怎么生成的呢? - apple的回答 - SegmentFault 思否](https://segmentfault.com/q/1010000004104517/a-1020000014209988) * * * * * ```php // tpDb操作出错要抛出异常,只能这么处理了。 // 如果这步骤出错,基本就是重复的问题,那么一直重试,再次生成邀请码更新进去,直至成功 do { try { // 生成唯一邀请码 Db::name('user')->where('id', $newId)->update([ 'invitation_code' => createInvitationCode(), ]); $upStatus = 1; } catch (\Exception $e) { trace('createInvitationCode: [' . $e->getCode() . '] ' . $e->getMessage(), 'error'); $upStatus = 0; } } while ($upStatus == 0); ``` * * * * * ### 扩展 [分布式ID生成器 | 架构师之路](http://mp.weixin.qq.com/s/AHRCYOjnXAgcy2j6vziukQ) [如何做一个靠谱的发号器](https://tech.youzan.com/id_generator/) * * * * * last update:2018-4-10 04:45:12