vr-shopxo-plugin/docs/09_SHOPXO_CACHE_HANDBOOK.md

116 lines
3.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# ShopXO 缓存速查手册
## 核心结论
| 命题 | 结论 |
|------|------|
| 数据库查询自动缓存? | ❌ 否,必须手动显式包裹 |
| 哪些查询被缓存? | 仅代码中用 `MyCache()` / `cache()` 包装的 |
| `Db::name('x')->find()` 自动走 Redis | ❌ 直击 DB无中间层 |
| 缓存驱动切换 | 由后台 `common_data_is_use_redis_cache` 控制0=file, 1=redis |
| Redis 参数来源 | 从数据库配置表读取host/port/password |
---
## 缓存调用方式
### ShopXO 自有的 `MyCache()`
```php
// 读取(为空触发重新查询)
$data = MyCache($key);
// 写入(第三参数 = 秒数 expire
MyCache($key, $data, 3600);
// 删除
MyCache($key, null);
```
### ThinkPHP 原生 `cache()`
```php
cache($key, $value, $expire_seconds);
cache($key, null); // 删除
```
---
## vr_ticket 插件缓存策略
### 缓存场景
| 数据 | 缓存时间 | 原因 |
|------|---------|------|
| 座位模板vr_seat_templates | 86400s1天 | 静态数据,变更少 |
| 商品座位图渲染数据 | 3600s1小时 | 商品信息不频繁改 |
| 核销记录列表 | 300s5分钟 | 需要一定实时性 |
| 观演人信息 | ❌ 不缓存 | 隐私数据 |
| 座位实时余量 | ❌ 不缓存 | 强一致性要求,走 DB |
### 缓存 Key 规范
```
vrticket:seat_template_{id} # 单个模板
vrticket:seat_templates_list # 模板列表
vrticket:goods_seat_map_{goods_id} # 商品座位图
vrticket:verifications_list # 核销记录列表
```
### 数据变更时主动失效
```php
// 模板更新后
cache('vrticket:seat_template_' . $id, null);
cache('vrticket:seat_templates_list', null);
// 核销记录新增后
cache('vrticket:verifications_list', null);
```
---
## 配置说明config/cache.php
```php
'default' => (MyFileConfig('common_data_is_use_redis_cache','',0,true) == 1) ? 'redis' : 'file',
'stores' => [
'redis' => [
'host' => MyFileConfig('common_cache_data_redis_host','','127.0.0.1',true),
'port' => MyFileConfig('common_cache_data_redis_port','',6379,true),
'password' => MyFileConfig('common_cache_data_redis_password','','',true),
'expire' => intval(MyFileConfig('common_cache_data_redis_expire','',0,true)),
'prefix' => MyFileConfig('common_cache_data_redis_prefix','','redis_shopxo',true),
],
]
```
- 全局 `expire` = 0 表示永久(受实际 per-key expire 覆盖)
- ShopXO 后台可配置 `common_data_is_use_cache` 全局开关debug 模式下自动 bypass
---
## 防坑提示
1. **Debug 模式绕过缓存**`MyEnv('app_debug')` 为 true 时所有 `MyCache()` 直接 miss
2. **全局开关**`MyC('common_data_is_use_cache') != 1` 时全部走 DB
3. **超卖风险**:座位状态查询禁止缓存,必须实时查 DB + `FOR UPDATE SKIP LOCKED`
4. **MyCache 静态复用**:同一请求内同一 key 只调一次底层 `cache()`in-request 内存缓存)
---
## 快速上手模板
```php
// 读缓存
$key = 'vrticket:seat_template_' . $templateId;
$data = MyCache($key);
if ($data === null) {
$data = Db::name('SeatTemplate')->where(['id'=>$templateId])->find();
MyCache($key, $data, 86400);
}
// 写操作后清缓存
cache('vrticket:seat_template_' . $templateId, null);
```