ソースを参照

库存修改增加锁

林琦海 5 年 前
コミット
e1d3c15269

+ 6 - 0
biz-ghs/product/classes/ProductClass.php

@@ -341,11 +341,17 @@ class ProductClass extends BaseClass
     //todo 库存修改 加锁
     public static function updateStockById($id, $stock, $adminId = 0)
     {
+        $key = self::LOCK_STOCK.'_'.$id;
+        $lock = util::lock($key);
+        if(!$lock){
+            util::fail("系统繁忙中,请稍后再试!");
+        }
         $data['stock'] = $stock;
         if($adminId){
             $data['adminId'] = $adminId;
         }
         $res =  self::updateById($id, $data);
+        util::unlock($key);
         return $res;
     }
 

+ 16 - 6
common/components/arrayUtil.php

@@ -4,7 +4,7 @@ namespace common\components;
 
 class arrayUtil
 {
-	
+
 	//二维数组排序(此方法有问题,不要使用,不要删除)
 	public static function sort($array, $row, $type = 'asc')
 	{
@@ -20,7 +20,7 @@ class arrayUtil
 		}
 		return $array_temp;
 	}
-	
+
 	//二维数组根据某个字段排序 $key键名
 	public static function arraySort($array, $key, $sort = SORT_DESC)
 	{
@@ -31,7 +31,7 @@ class arrayUtil
 		array_multisort($data, $sort, $array);
 		return $array;
 	}
-	
+
 	/**
 	 * 把返回的数据集转换成Tree
 	 * @param array $list 要转换的数据集
@@ -63,7 +63,7 @@ class arrayUtil
 		}
 		return $tree;
 	}
-	
+
 	/**
 	 * 把返回的数据集转换成Tree(id作为键名)
 	 * @param array $rows 要转换的数据集
@@ -83,5 +83,15 @@ class arrayUtil
 		}
 		return isset($items[0][$child]) ? $items[0][$child] : [];
 	}
-	
-}
+
+	//2021.2.23 linqh  返回二维数组中某个单一列的值
+    /**
+     * @param array $arr
+     * @param string $col
+     * @return array
+     */
+	public static function arrayColumn(array $arr,string $col)
+    {
+        return array_unique(array_filter(array_column($arr, $col)));
+    }
+}

+ 71 - 1
common/components/util.php

@@ -302,4 +302,74 @@ class util
         self::encode(['code' => -1, 'msg' => $msg, 'data' => []]);
     }
 
-}
+    /**
+     * [getLock 时间锁]
+     * @param  [type]  $key    [string]
+     * @param  integer $expire [time]
+     * @return [type]          [bool]
+     */
+    public static function getLock($key, $expire = 10)
+    {
+
+        $redis = Yii::$app->redis;
+        return $redis->setex($key, $expire,time());
+    }
+
+    /**
+     * 检测锁是否存在
+     * @param $key
+     * @return bool
+     */
+    public static function checkLock($key)
+    {
+        $redis = Yii::$app->redis;
+        if($redis->get($key)){
+            return true;
+        }
+        else{
+            return false;
+        }
+    }
+
+    /**
+     * 获取锁
+     * @param String $key 锁标识
+     * @param Int $expire 锁过期时间
+     * @param Int $retry 等待次数
+     * @return Boolean
+     */
+    public static function lock($key, $expire = 5,$retry = 20)
+    {
+        $redis = Yii::$app->redis;
+        $is_lock = $redis->setex($key,$expire, time() + $expire);
+        // 不能获取锁
+        if (!$is_lock) {
+            // 判断锁是否过期 锁已过期 删除锁 重新获取 防止过期时间设置长,结束时没主动调unlock
+            $lock_time = $redis->get($key);
+            if($lock_time && time()>$lock_time){
+                self::unlock($key);
+                $is_lock = $redis->set($key, time()+$expire, ['nx', 'ex' => $expire]);
+            }
+            if(!$is_lock && $retry){
+                do {
+                    $retry -= 1;
+                    usleep(10000);
+                    $is_lock = $redis->setex($key,$expire ,time() + $expire);
+                } while(!$is_lock && $retry);
+            }
+        }
+        return $is_lock ? true : false;
+    }
+
+    /**
+     * 释放锁
+     * @param String $key 锁标识
+     * @return Boolean
+     */
+    public static function unlock($key)
+    {
+        $redis = Yii::$app->redis;
+        return $redis->del($key);
+    }
+
+}