Commit 6b54ac20 authored by liuyuzhen's avatar liuyuzhen

锁相关

parent 5bcf2e3c
......@@ -201,4 +201,8 @@ class HomeController extends \Our\Controller_AbstractIndex{
}
}
public function writeToFileAction(){
\Business\User\AddressServiceModel::getInstance()->writeToFile();
}
}
\ No newline at end of file
......@@ -7,7 +7,7 @@ namespace Lock;
* Description:
*/
interface ILock{
const EXPIRE = 5;
const EXPIRE = 1;
public function getLock($key, $timeout = self::EXPIRE);
......
......@@ -12,22 +12,30 @@ class RedisLock implements \Lock\ILock{
public function __construct()
{
$this->lockRedis = \Redis\Db0\LockRedisModel::getInstance();
$this->lockRedis = \Redis\Db1\LockRedisModel::getInstance();
}
public function getMicrotime(){
list($msec, $sec) = explode(' ', microtime());
$msectime = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
return $msectime;
}
public function getLock($key, $timeout=self::EXPIRE)
{
$waitime = 20000;
$totalWaitime = 0;
$time = $timeout*1000000;
while ($totalWaitime < $time && false == $this->lockRedis->update($key, 1, $timeout)){
usleep($waitime);
$totalWaitime += $waitime;
}
if ($totalWaitime >= $time){
\Our\Log::getInstance()->write($key.' can not get lock for waiting '.$timeout.'s.');
throw new Exception('can not get lock for waiting '.$timeout.'s.');
$currMicroTime = $this->getMicrotime();
$is_lock = $this->lockRedis->tableSetnx($key, $currMicroTime+200);
// 不能获取锁
if(!$is_lock){
//判断锁是否过期
$lock_time = $this->lockRedis->get($key);
// 锁已过期,删除锁,重新获取
if($currMicroTime>(float)$lock_time){
$this->releaseLock($key);
$is_lock = $this->lockRedis->setnx($key, $currMicroTime+$timeout);
}
}
return $is_lock? true : false;
}
public function releaseLock($key)
......
......@@ -48,14 +48,21 @@ class OrderConfirmUtil {
private $couponCacheFlag = false;
public function addOrder($data,$memberId,$currentAddress){
$storeCartData = $this->checkPostData($data,$memberId,$currentAddress);
//return $storeCartData;
if(CURRENTVERSION==\Our\NameConst::versionDefault){
$storeCartData = $this->checkDeliveryTypeAndPayway($storeCartData);
$isLock = \Lock\RedisLock::getInstance()->getLock('addOrder');
if($isLock){
$storeCartData = $this->checkPostData($data,$memberId,$currentAddress);
//return $storeCartData;
if(CURRENTVERSION==\Our\NameConst::versionDefault){
$storeCartData = $this->checkDeliveryTypeAndPayway($storeCartData);
}else{
$storeCartData = $this->checkDeliveryTypeAndPaywayNew($storeCartData);
}
$result = $this->saveOrderInfo($storeCartData);
\Lock\RedisLock::getInstance()->releaseLock('addOrder');
return $result;
}else{
$storeCartData = $this->checkDeliveryTypeAndPaywayNew($storeCartData);
\Error\ErrorModel::throwException(\Error\CodeConfigModel::addOrderFrequently);
}
return $this->saveOrderInfo($storeCartData);
}
......
......@@ -69,6 +69,51 @@ class AreaModel extends \DAO\AbstractModel {
return $areaList;
}
public function writeToFile(){
$this->setDb($this->dbName);
$where = array('area_deep'=>array('neq',3));
$where= $this->db->getSqlWhereByArray($where);
$areaList = $this->db->select(\Our\NameConst::allField)->from($this->_tableName)->where($where)->order('area_deep','asc')->fetchAll();
$where = array('area_deep'=>3);
$areaSubList = $this->db->select(\Our\NameConst::allField)->from($this->_tableName)->where($where)->limit(0,3000)->order('area_id','asc')->fetchAll();
var_dump(count($areaSubList));
$proInfoList = array();
foreach($areaList as $area){
if($area['area_deep']==1){
$proInfoList[$area['area_id']]['area_name'] = $area['area_name'];
}else{
$city = array();
$city['city_name'] = $area['area_name'];
$city['city_id'] = $area['area_id'];
$proInfoList[$area['area_parent_id']]['list'][] = $city;
}
}
$newAreaList = array();
foreach($areaSubList as $area){
$newAreaList[$area['area_parent_id']][]= $area['area_name'];
}
$returnList = array();
$proList = array();
foreach($proInfoList as $proInfo){
$return = array();
$return['name'] = $proInfo['area_name'];
$return['city'] = array();
if($proInfo['list']){
foreach($proInfo['list'] as $city){
$newCity= array();
$newCity['name'] = $city['city_name'];
$newCity['area'] = $newAreaList[$city['city_id']]?$newAreaList[$city['city_id']]:array();
var_dump($newCity);
array_push($return['city'],$newCity);
}
}
$returnList[] = $return;
}
\Our\Log::getInstance()->write(json_encode($returnList),'/data/log/appcity');
return $returnList;
}
public function getCityListWithoutCounty(){
$addressRedis = AddressRedisModel::getInstance();
$cityList = $addressRedis->find('cityListWithoutCounty');
......
......@@ -105,6 +105,7 @@ class CodeConfigModel
const notHaveAccess = 10117;
const sellerJoinUpdateFailed = 10118;
const passwordLenLimit = 10119;
const redisLockedFailed = 10120;
//访问错误
const illegalAccess = 200001;
......@@ -326,6 +327,7 @@ class CodeConfigModel
const beyondRecieverTime=300144;
const payTypeUpdateError = 30145;
const beyongRefundAmount = 300146;
const addOrderFrequently = 300147;
//店铺相关错误码
//商品分类
......@@ -481,7 +483,7 @@ class CodeConfigModel
self::emptyDeviceUniqueCode => '设备唯一识别码不能为空',
self::addMemberInfoFailed => '注册保存用户信息失败',
self::wrongMobileFormat => '手机号码格式错误',
self::registerMobileExist => '您的手机号码已经存在',
self::registerMobileExist => '该手机号码已注册',
self::emptyUserType => '用户来源不能为空',
self::wrongUserType => '用户只能来自微博、QQ、微信',
self::emptyUserAvatar => '第三方用户头像不能为空',
......@@ -538,7 +540,8 @@ class CodeConfigModel
self::sellerNameUpdateFailed => '更换手机时卖家手机号码更新失败',
self::notHaveAccess => '您没有权限使用',
self::sellerJoinUpdateFailed => '更换手机时卖家手机号码更新失败',
self::passwordLenLimit => '密码为6~16位的数字或字母组合',
self::passwordLenLimit => '密码长度不能小于6位',
self::redisLockedFailed => '获取redis锁失败',
//商品相关
self::emptyCommonId => '商品主键不能为空',
self::goodsNotExist => '商品不存在',
......@@ -834,6 +837,7 @@ class CodeConfigModel
self::beyondRecieverTime=>'设置收货时间不能早于当前时间',
self::payTypeUpdateError=> '更新支付类型失败',
self::beyongRefundAmount=>'退款金额不能超过可退款金额',
self::addOrderFrequently => '操作太频繁,请稍后重试',
//销售员
self::emptySaleGoodsId => '商品id不能为空',
self::emptySaleGoods => '销售商品不存在',
......
......@@ -15,6 +15,7 @@ class ErrorModel {
* @throws \Exception
*/
public static function throwException($code, $message = null) {
\Lock\RedisLock::getInstance()->releaseLock('addOrder');
if (!$message) {
$codeConfig = \Error\CodeConfigModel::getCodeConfig();
if (empty($codeConfig[$code])) {
......
......@@ -36,6 +36,9 @@ class LinkMySQLModel{
public static function get($database='resources.database.slave.params') {
if ( empty(self::$_configs[$database]) ) {
if($database===true){
$database = 'resources.database.params';
}
$config = \Yaf\Registry::get('config')->get($database);
$config = $config->toArray();
self::$_configs[$database]=$config;
......
......@@ -89,7 +89,9 @@ class AbstractModel {
* @return
*/
public function del($key) {
return $this->getRedis()->del($this->_addPrefix($key));
$keyNEw = $this->_addPrefix($key);
var_dump($keyNEw);
return $this->getRedis()->del($keyNEw);
}
public function delAll($data){
return $this->getRedis()->del($data);
......@@ -135,6 +137,13 @@ class AbstractModel {
return $this->getRedis()->get($this->_addPrefix($key));
}
public function setnx($key, $value,$expire=\Our\ApiConst::zero){
$res=$this->getRedis()->setnx($this->_addPrefix($key),$value);
if($expire>0){
$this->getRedis()->expire($this->_addPrefix($key),$expire);
}
return $res;
}
public function getNoPrefix($key){
return $this->getRedis()->get($key);
......
<?php
namespace Redis\Db0;
namespace Redis\Db1;
/**
* User: liuyuzhen
* Date: 2018/8/20
* Time: 10:30
* Description:
*/
class LockRedisModel extends \Redis\Db0\AbstractModel {
class LockRedisModel extends \Redis\Db1\AbstractModel {
/**
* 表名
*
......@@ -72,6 +72,10 @@ class LockRedisModel extends \Redis\Db0\AbstractModel {
return $this->del($this->calcKey($h));
}
public function tableSetnx($id,$data,$experio=\Our\ApiConst::zero){
$res=$this->setnx($this->calcKey($id), $data,$experio);
return $res;
}
public function tableExpire($key,$experio=0){
return $this->expire($this->calcKey($key),$experio);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment