1, Memcache => 2, Redis => 3 */ public function incId($type, $prefix ,$length, $fixed=false) { //获取可能存在的可用于产生自增量的系统,如 redis, memcache 等 $cacheObj = $incObj = $this->_getIncGenerater(); $key = $prefix; if (is_object($incObj)) { //根据 fixed 传入值,产生用于组成唯一GUID的前半部分内容 if ($fixed) { $key = $prefix . $incObj->getUUIDFix(); } //如系统有可用配置,则使用可用的对像来产生对应类型的自增 $cachekey = $this->_createKey($key, $type); $step = $incObj->increment($cachekey); //判断如果自增id,验证是否是异常情况链接不上导致的id重置为1,检查数据库是否已存在 if ($step == 1) { $numid = $key . str_pad($step, $length,'0',STR_PAD_LEFT); if ($this->_existGUID($type, $numid)) { $step = false; } } } else { //不存在,赋值为false,让系统后续使用数据库方式获取 $step = false; } //如获取失败,使用数据库获取 if ($step === false) { $incObj = $this->_getIncDbGUID(); if ($fixed) { $key = $prefix . $incObj->getUUIDFix(); } $step = $incObj->increment($type, $prefix ,$length, $fixed); //根据数据库计算的自增id重置缓存中的值 if (is_object($cacheObj)) { $cacheObj->store($cachekey, $step); } } //根据传入的参数来生成可用的GUID $guid = $key . str_pad($step, $length,'0',STR_PAD_LEFT); //在数据库中进行保存,进行可用性校验,并保证在缓存类产生对像不可用的情况下,能使用数据库产生合适的可用GUID if ($this->_vaildGUID($type, $guid)) { return $guid; } else { //重新生成一次 return $this->incId($type, $prefix ,$length, $fixed); } } /** * 保存数据库,并检查是否有重复 * * @return Boolean */ private function _vaildGUID($type, $guid) { return $this->_getIncDbGUID()->_vaildGUID($type, $guid); } /** * ID是否存在 * * @return void * @author * */ private function _existGUID($type, $guid) { return $this->_getIncDbGUID()->_existGUID($type, $guid); } /** * 获取实际KEY值 * * @return String */ private function _createKey($key, $type) { return sprintf("%s_%s_%s", 'S_GUID', strtoupper($type), strtoupper($key)); } /** * 获取用于产生唯一自增ID的对像 * * @return Object */ private function _getIncGenerater() { if (base_kvstore::instance('uuid')->supportUUID()) { //先检查是否KV支持自增型操作 return base_kvstore::instance('uuid'); } elseif(cachecore::instance()->supportUUID()) { //再检查是否缓存模块是否支持自增型操作 return cachecore::instance(); } else { return false;//$this->_getIncDbGUID(); } } /** * 返回使用数据库产生唯一自增ID的对像 * * @return Object */ private function _getIncDbGUID() { return ome_concurrent_guid::instance(); } }