Commit 810704da authored by liuyuzhen's avatar liuyuzhen

常见问题以及锁

parent 9dd26ec3
...@@ -57,4 +57,11 @@ class CommonController extends \Our\Controller_AbstractIndex{ ...@@ -57,4 +57,11 @@ class CommonController extends \Our\Controller_AbstractIndex{
$this->success(array(),\Our\DescribeConst::emptyMyAddresses,\Our\DescribeConst::emptyMyAddresses); $this->success(array(),\Our\DescribeConst::emptyMyAddresses,\Our\DescribeConst::emptyMyAddresses);
} }
public function getListAction(){
$commonProbleService = \Business\Common\CommonProblemServiceModel::getInstance();
$articleList = $commonProbleService->getProblemList(true);
$this->success($articleList);
}
} }
\ No newline at end of file
<?php <?php
/** namespace Lock;
* User: liuyuzhen /**
* Date: 2018/8/20 * User: liuyuzhen
* Time: 11:02 * Date: 2018/8/20
* Description: * Time: 11:02
*/ * Description:
\ No newline at end of file */
class DbLock implements \Lock\ILock{
private $lockModel ;
public function __construct(){
$this->lockModel = \DAO\LockModel::getInstance();
}
public function getLock($key, $timeout=self::EXPIRE){
return $this->lockModel->getLock($key, $timeout);
}
public function releaseLock($key){
return $this->lockModel->releaseLock($key);
}
/**
* 类实例
*
*/
private static $_instance = null;
/**
* 获取类实例
*/
public static function getInstance() {
if (!(self::$_instance instanceof self)) {
self::$_instance = new self();
}
return self::$_instance;
}
}
\ No newline at end of file
<?php <?php
/** namespace Lock;
* User: liuyuzhen /**
* Date: 2018/8/20 * User: liuyuzhen
* Time: 10:10 * Date: 2018/8/20
* Description: * Time: 10:10
*/ * Description:
\ No newline at end of file */
class FileLock implements \Lock\ILock{
private $_fp;
private $_single;
public function __construct($options)
{
if (isset($options['path']) && is_dir($options['path']))
{
$this->_lockPath = $options['path'].'/';
}
else
{
$this->_lockPath = '/tmp/';
}
$this->_single = isset($options['single'])?$options['single']:false;
}
public function getLock($key, $timeout=self::EXPIRE)
{
$startTime = TIMESTAMP;
$file = md5(__FILE__.$key);
$this->fp = fopen($this->_lockPath.$file.'.lock', "w+");
if (true || $this->_single)
{
$op = LOCK_EX + LOCK_NB;
}
else
{
$op = LOCK_EX;
}
if (false == flock($this->fp, $op, $a))
{
throw new Exception('failed');
}
return true;
}
public function releaseLock($key)
{
flock($this->fp, LOCK_UN);
fclose($this->fp);
}
}
\ No newline at end of file
<?php <?php
/** namespace Lock;
* User: liuyuzhen /**
* Date: 2018/8/20 * User: liuyuzhen
* Time: 10:09 * Date: 2018/8/20
* Description: * Time: 10:09
*/ * Description:
\ No newline at end of file */
interface ILock{
const EXPIRE = 5;
public function getLock($key, $timeout = self::EXPIRE);
public function releaseLock($key);
}
\ No newline at end of file
<?php <?php
/** namespace Lock;
* User: liuyuzhen /**
* Date: 2018/8/20 * User: liuyuzhen
* Time: 11:18 * Date: 2018/8/20
* Description: * Time: 11:18
*/ * Description:
\ No newline at end of file */
class LockConst {
const goodsStoreagePrefix = 'goodsStorage_';
}
\ No newline at end of file
<?php
namespace Lock;
/**
* User: liuyuzhen
* Date: 2018/8/20
* Time: 15:30
* Description:
*/
class LockSystem{
const LOCK_TYPE_DB = 'DbLock';
const LOCK_TYPE_FILE = 'FileLock';
const LOCK_TYPE_REDIS = 'RedisLock';
private $_lock = null;
private static $_supportLocks = array('FileLock', 'DbLock', 'RedisLock');
public function __construct($type, $options = array()){
if(false == empty($type))
{
$this->createLock($type, $options);
}
}
public function createLock($type, $options=array()){
if (false == in_array($type, self::$_supportLocks))
{
throw new Exception("not support lock of ${type}");
}
$this->_lock = new $type($options);
}
public function getLock($key, $timeout = \Lock\ILock::EXPIRE){
if (false == $this->_lock instanceof \Lock\ILock)
{
throw new Exception('false == $this->_lock instanceof ILock');
}
$this->_lock->getLock($key, $timeout);
}
public function releaseLock($key){
if (false == $this->_lock instanceof \Lock\ILock)
{
throw new Exception('false == $this->_lock instanceof ILock');
}
$this->_lock->releaseLock($key);
}
/**
* 类实例
*
*/
private static $_instance = null;
/**
* 获取类实例
*/
public static function getInstance($type,$options= array()) {
if (!(self::$_instance instanceof self)) {
self::$_instance = new self($type,$options);
}
return self::$_instance;
}
}
\ No newline at end of file
<?php <?php
/** namespace Lock;
* User: liuyuzhen /**
* Date: 2018/8/20 * User: liuyuzhen
* Time: 10:48 * Date: 2018/8/20
* Description: * Time: 10:48
*/ * Description:
\ No newline at end of file */
class RedisLock implements \Lock\ILock{
private $lockRedis ;
public function __construct()
{
$this->lockRedis = \Redis\Db0\LockRedisModel::getInstance();
}
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.');
}
}
public function releaseLock($key)
{
$this->lockRedis->tableDel($key);
}
/**
* 类实例
*
*/
private static $_instance = null;
/**
* 获取类实例
*/
public static function getInstance() {
if (!(self::$_instance instanceof self)) {
self::$_instance = new self();
}
return self::$_instance;
}
}
\ No newline at end of file
...@@ -92,6 +92,14 @@ class Common ...@@ -92,6 +92,14 @@ class Common
return $configValue; return $configValue;
} }
public static function getBaseUrl(){
$prefix = 'http';
if(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on'){
$prefix = 'https';
}
$url = $prefix.'://'.$_SERVER['SERVER_NAME'];
return $url;
}
/** /**
......
...@@ -8,9 +8,14 @@ namespace Business\Common; ...@@ -8,9 +8,14 @@ namespace Business\Common;
*/ */
class CommonProblemServiceModel extends \Business\AbstractModel{ class CommonProblemServiceModel extends \Business\AbstractModel{
public function getProblemList(){ public function getProblemList($urlFlag=false){
$articleDao = \DAO\Article\ArticleModel::getInstance(); $articleDao = \DAO\Article\ArticleModel::getInstance();
$articleList = \Our\RedisHelper::cachedFunction(\Redis\Db10\ArticleRedisModel::getInstance(),array(&$articleDao, 'getList'),array(array('ac_id'=>\Our\ApiConst::commonProblemArticleClassId),'article_id as problemId,article_title as problemTitle',array('article_sort'=>'asc','article_id'=>'desc')),\Our\ApiConst::oneHour,array(\Our\ApiConst::commonProblemArticleClassId)); $articleList = \Our\RedisHelper::cachedFunction(\Redis\Db10\ArticleRedisModel::getInstance(),array(&$articleDao, 'getList'),array(array('ac_id'=>\Our\ApiConst::commonProblemArticleClassId),'article_id as problemId,article_title as problemTitle',array('article_sort'=>'asc','article_id'=>'desc')),\Our\ApiConst::oneHour,array(\Our\ApiConst::commonProblemArticleClassId));
if($urlFlag){
foreach($articleList as &$article){
$article['problemUrl'] = '/qa/detail?id='.$article['problemId'];
}
}
return $articleList; return $articleList;
} }
......
...@@ -283,6 +283,10 @@ class MemberServiceModel extends \Business\AbstractModel ...@@ -283,6 +283,10 @@ class MemberServiceModel extends \Business\AbstractModel
$result = $storeMemberDao->addBatch($storeMember); $result = $storeMemberDao->addBatch($storeMember);
return $result; return $result;
} }
$scan_sale_ids = $sess->get('scan_sale_ids');
if($scan_sale_ids){
\DAO\SaleModel::getInstance()->getList(array('sale_id'=>array('in',$scan_sale_ids)),'sale_act_id,member_id');
}
return true; return true;
} }
......
<?php <?php
/** namespace DAO;
* User: liuyuzhen /**
* Date: 2018/8/20 * User: liuyuzhen
* Time: 10:15 * Date: 2018/8/20
* Description: * Time: 10:15
*/ * Description:
\ No newline at end of file */
class LockModel extends \DAO\AbstractModel{
public function init(){
}
public function getLock($key, $timeout)
{
$sql = "SELECT GET_LOCK('".$key."', '".$timeout."')";
$res = $this->db->query($sql);
return $res;
}
public function releaseLock($key)
{
$sql = "SELECT RELEASE_LOCK('".$key."')";
return $this->db->query($sql);
}
/**
* 类实例
*
* @var \DAO\UserModel
*/
private static $_instance = null;
/**
* 获取类实例
*
* @return \DAO\UserModel
*/
public static function getInstance($dbName = \Our\DbNameConst::salveDBConnectName) {
if (!(self::$_instance instanceof self)) {
self::$_instance = new self($dbName);
}
return self::$_instance;
}
}
\ No newline at end of file
...@@ -116,17 +116,48 @@ class SaleMemberModel extends \DAO\AbstractModel { ...@@ -116,17 +116,48 @@ class SaleMemberModel extends \DAO\AbstractModel {
$this->setDb(\Our\DbNameConst::masterDBConnectName); $this->setDb(\Our\DbNameConst::masterDBConnectName);
return $this->db->insert($this->_tableName)->rows($data)->execute(); return $this->db->insert($this->_tableName)->rows($data)->execute();
} }
public function insertAllOrUpdate($datas){
$this->setDb(\Our\DbNameConst::masterDBConnectName);
$error = 0;
$baseSql = "insert into {$this->_tableName}(sale_id,sale_act_id,member_id,store_id) values";
$insertAllSql = $baseSql;
for ($i = 0; $i < count($datas); $i++) {
$addSql = \Our\Common::format("('{0}','{1}','{2}','{3}'),", $datas[$i]['sale_id'], $datas[$i]['sale_act_id'], $datas[$i]['member_id'], $datas[$i]['store_id']);
$insertAllSql .= $addSql;
if ($i % 1000 == 0 && $i != 0) {
$insertAllSql = rtrim($insertAllSql, ',');
$insertAllSql .= 'ON DUPLICATE KEY UPDATE sale_id = VALUES(sale_id)';
$one = $this->db->insert()->query($insertAllSql);
if ($one === false) {
$error++;
}
$insertAllSql = $baseSql;
}
}
if ($insertAllSql != $baseSql) {
$insertAllSql = rtrim($insertAllSql, ',');
$insertAllSql .= 'ON DUPLICATE KEY UPDATE sale_id = VALUES(sale_id)';
$one = $this->db->insert($this->_tableName)->query($insertAllSql);
if ($one === false) {
$error++;
}
}
if ($error > 0) {
return false;
}
return true;
}
/** /**
* 类实例 * 类实例
* *
* @var \DAO\UserModel
*/ */
private static $_instance = null; private static $_instance = null;
/** /**
* 获取类实例 * 获取类实例
* *
* @return \DAO\UserModel
*/ */
public static function getInstance() { public static function getInstance() {
if (!(self::$_instance instanceof self)) { if (!(self::$_instance instanceof self)) {
......
<?php <?php
namespace Redis\Db0; namespace Redis\Db0;
/** /**
* User: liuyuzhen * User: liuyuzhen
* Date: 2018/8/20 * Date: 2018/8/20
* Time: 10:30 * Time: 10:30
* Description: * Description:
*/ */
\ No newline at end of file class LockRedisModel extends \Redis\Db0\AbstractModel {
/**
* 表名
*
* @var string
*/
protected $_tableName = 'han_lock';
/**
* 计算key
*
* @param int $id
* @return string
*/
public function calcKey($id) {
return $this->_tableName . self::DELIMITER . $id;
}
/**
* 根据id查找用户信息
*
* @param int $id
* @return array
*/
public function find($id) {
$result = $this->get($this->calcKey($id));
if ($result) {
return json_decode($result, true);
}
return null;
}
/**
* 更新数据
*
* @param int $id
* @param array $data
*/
public function update($id, $data,$expire=\Our\ApiConst::zero) {
return $this->set($this->calcKey($id), json_encode($data),$expire);
}
public function tableHSet($h,$key,$val,$experio=0){
return $this->hset($this->calcKey($h),$key,$val,$experio);
}
public function tableHGet($h,$key){
return $this->hget($this->calcKey($h),$key);
}
public function tableHMSet($h,$keysvalue,$experio=0){
return $this->hmset($this->calcKey($h),$keysvalue,$experio);
}
public function tableHMGet($h,$keyvalues){
return $this->hmget($this->calcKey($h),$keyvalues);
}
public function tableHGAll($h){
return $this->hGetAll($this->calcKey($h));
}
public function tableDel($h){
return $this->del($this->calcKey($h));
}
public function tableExpire($key,$experio=0){
return $this->expire($this->calcKey($key),$experio);
}
public function tableCacheGet($id){
$result = $this->get($this->calcKey($id));
return $result;
}
public function tableCacheSet($id,$data,$experio){
$res=$this->set($this->calcKey($id), $data,$experio);
return $res;
}
/**
* 类实例
*
*/
private static $_instance = null;
/**
* 获取类实例
*/
public static function getInstance() {
if (!(self::$_instance instanceof self)) {
self::$_instance = new self();
}
return self::$_instance;
}
}
\ No newline at end of file
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