From 23c1d76661d25bc3e1a7f573fa4a38b0f6911c60 Mon Sep 17 00:00:00 2001 From: ityifan <329686198@qq.com> Date: Wed, 17 Sep 2025 15:36:33 +0800 Subject: [PATCH 01/26] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E7=BC=93=E5=AD=98=E6=BB=9E=E5=90=8E=E6=89=A7=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libs/MysqlBin.ts | 25 +++++- src/services/MysqlCache.ts | 67 +++++++++++---- src/test/demo.ts | 168 +++++++++++++++---------------------- 3 files changed, 140 insertions(+), 120 deletions(-) diff --git a/src/libs/MysqlBin.ts b/src/libs/MysqlBin.ts index 21c8f35..937e35e 100644 --- a/src/libs/MysqlBin.ts +++ b/src/libs/MysqlBin.ts @@ -1,8 +1,10 @@ import { echo } from 'coa-echo' import { CoaError } from 'coa-error' -import { Knex } from './Knex' +import { MysqlCache } from '../services/MysqlCache' import { CoaMysql } from '../typings' +import { Knex } from './Knex' +import { secure } from 'coa-secure' export class MysqlBin { public io: Knex public config: CoaMysql.Config @@ -30,4 +32,25 @@ export class MysqlBin { this.config = config this.io = io } + + async safeTransaction(handler: (trx: CoaMysql.Transaction) => Promise): Promise { + let cacheTasks: Array<{ model: MysqlCache, ids: string[], dataList: any[] }> = [] + + const result = await this.io.transaction(async (trx: any) => { + trx.registerCacheClear = (model: MysqlCache, ids: string[], dataList: any[]) => { + cacheTasks.push({ model, ids, dataList }) + trx.id ||= secure.id25(`${Date.now()}-${model}`) + } + + return await handler(trx) + }) + + for (const task of cacheTasks) { + await task.model.deleteCache(task.ids, task.dataList) + } + // 初始数组 减少trx未及时销毁时的内存占用 + cacheTasks = [] + + return result + } } diff --git a/src/services/MysqlCache.ts b/src/services/MysqlCache.ts index 7ccd92c..199daf1 100644 --- a/src/services/MysqlCache.ts +++ b/src/services/MysqlCache.ts @@ -1,3 +1,4 @@ +import { echo } from 'coa-echo' import { CoaError } from 'coa-error' import { $, _ } from 'coa-helper' import { CoaRedis, RedisCache } from 'coa-redis' @@ -5,7 +6,6 @@ import { secure } from 'coa-secure' import { MysqlBin } from '../libs/MysqlBin' import { CoaMysql } from '../typings' import { MysqlNative } from './MysqlNative' - export class MysqlCache extends MysqlNative { redisCache: RedisCache @@ -16,48 +16,62 @@ export class MysqlCache extends MysqlNative { async insert(data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const id = await super.insert(data, trx) - await this.deleteCache([id], [data]) + if (id) { + (trx && (trx as any).registerCacheClear) ? (trx as any).registerCacheClear(this, [id], data) : await this.deleteCache([id], [data]) + } return id } async mInsert(dataList: Array>, trx?: CoaMysql.Transaction) { const ids = await super.mInsert(dataList, trx) - await this.deleteCache(ids, dataList) + if (ids) { + (trx && (trx as any).registerCacheClear) ? (trx as any).registerCacheClear(this, ids, dataList) : await this.deleteCache(ids, dataList) + } return ids } async updateById(id: string, data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList([id], data, trx) const result = await super.updateById(id, data, trx) - if (result) await this.deleteCache([id], dataList) + if (result) { + (trx && (trx as any).registerCacheClear) ? (trx as any).registerCacheClear(this, [id], dataList) : await this.deleteCache([id], dataList) + } return result } async updateByIds(ids: string[], data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList(ids, data, trx) const result = await super.updateByIds(ids, data, trx) - if (result) await this.deleteCache(ids, dataList) + if (result) { + (trx && (trx as any).registerCacheClear) ? (trx as any).registerCacheClear(this, ids, dataList) : await this.deleteCache(ids, dataList) + } return result } async updateForQueryById(id: string, query: CoaMysql.Query, data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList([id], data, trx) const result = await super.updateForQueryById(id, query, data, trx) - if (result) await this.deleteCache([id], dataList) + if (result) { + (trx && (trx as any).registerCacheClear) ? (trx as any).registerCacheClear(this, [id], dataList) : await this.deleteCache([id], dataList) + } return result } async upsertById(id: string, data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList([id], data, trx) const result = await super.upsertById(id, data, trx) - await this.deleteCache([id], dataList) + if (result) { + (trx && (trx as any).registerCacheClear) ? (trx as any).registerCacheClear(this, [id], dataList) : await this.deleteCache([id], dataList) + } return result } async deleteByIds(ids: string[], trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList(ids, undefined, trx) const result = await super.deleteByIds(ids, trx) - if (result) await this.deleteCache(ids, dataList) + if (result) { + (trx && (trx as any).registerCacheClear) ? (trx as any).registerCacheClear(this, ids, dataList) : await this.deleteCache(ids, dataList) + } return result } @@ -66,16 +80,19 @@ export class MysqlCache extends MysqlNative { } async getById(id: string, pick = this.columns, trx?: CoaMysql.Transaction, ms = this.ms, force = false) { - const result = await this.redisCache.warp(this.getCacheNsp('id'), id, async () => await super.getById(id, this.columns, trx), ms, force) + const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'id') : this.getCacheNsp('id') + const result = await this.redisCache.warp(cacheNsp, id, async () => await super.getById(id, this.columns, trx), ms, force) return this.pickResult(result, pick) } async getIdBy(field: string, value: string | number, trx?: CoaMysql.Transaction) { - return await this.redisCache.warp(this.getCacheNsp('index', field), '' + value, async () => await super.getIdBy(field, value, trx)) + const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'index', field) : this.getCacheNsp('index', field) + return await this.redisCache.warp(cacheNsp, '' + value, async () => await super.getIdBy(field, value, trx)) } async mGetByIds(ids: string[], pick = this.pick, trx?: CoaMysql.Transaction, ms = this.ms, force = false) { - const result = await this.redisCache.mWarp(this.getCacheNsp('id'), ids, async ids => await super.mGetByIds(ids, this.columns, trx), ms, force) + const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'id') : this.getCacheNsp('id') + const result = await this.redisCache.mWarp(cacheNsp, ids, async ids => await super.mGetByIds(ids, this.columns, trx), ms, force) _.forEach(result, (v, k) => { result[k] = this.pickResult(v, pick) }) @@ -88,32 +105,37 @@ export class MysqlCache extends MysqlNative { } protected async findListCount(finger: Array>, query: CoaMysql.Query, trx?: CoaMysql.Transaction) { - const cacheNsp = this.getCacheNsp('data') + // const cacheNsp = this.getCacheNsp('data') + const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'data') : this.getCacheNsp('data') const cacheId = 'list-count:' + secure.sha1($.sortQueryString(...finger)) return await this.redisCache.warp(cacheNsp, cacheId, async () => await super.selectListCount(query, trx)) } protected async findIdList(finger: Array>, query: CoaMysql.Query, trx?: CoaMysql.Transaction) { - const cacheNsp = this.getCacheNsp('data') + // const cacheNsp = this.getCacheNsp('data') + const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'data') : this.getCacheNsp('data') const cacheId = 'list:' + secure.sha1($.sortQueryString(...finger)) return await this.redisCache.warp(cacheNsp, cacheId, async () => await super.selectIdList(query, trx)) } protected async findIdSortList(finger: Array>, pager: CoaMysql.Pager, query: CoaMysql.Query, trx?: CoaMysql.Transaction) { - const cacheNsp = this.getCacheNsp('data') + // const cacheNsp = this.getCacheNsp('data') + const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'data') : this.getCacheNsp('data') const cacheId = `sort-list:${pager.rows}:${pager.last}:` + secure.sha1($.sortQueryString(...finger)) return await this.redisCache.warp(cacheNsp, cacheId, async () => await super.selectIdSortList(pager, query, trx)) } protected async findIdViewList(finger: Array>, pager: CoaMysql.Pager, query: CoaMysql.Query, trx?: CoaMysql.Transaction) { - const cacheNsp = this.getCacheNsp('data') + // const cacheNsp = this.getCacheNsp('data') + const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'data') : this.getCacheNsp('data') const cacheId = `view-list:${pager.rows}:${pager.page}:` + secure.sha1($.sortQueryString(...finger)) const count = await this.findListCount(finger, query, trx) return await this.redisCache.warp(cacheNsp, cacheId, async () => await super.selectIdViewList(pager, query, trx, count)) } protected async mGetCountBy(field: string, ids: string[], trx?: CoaMysql.Transaction) { - const cacheNsp = this.getCacheNsp('count', field) + // const cacheNsp = this.getCacheNsp('count', field) + const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'count', field) : this.getCacheNsp('count', field) return await this.redisCache.mWarp(cacheNsp, ids, async ids => { const rows = (await this.table(trx).select({ id: field }).count({ count: this.key }).whereIn(field, ids).groupBy(field)) as any[] const result: CoaMysql.Dic = {} @@ -123,7 +145,8 @@ export class MysqlCache extends MysqlNative { } protected async getCountBy(field: string, value: string, query?: CoaMysql.Query, trx?: CoaMysql.Transaction) { - const cacheNsp = this.getCacheNsp('count', field) + // const cacheNsp = this.getCacheNsp('count', field) + const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'count', field) : this.getCacheNsp('count', field) return await this.redisCache.warp(cacheNsp, value, async () => { const qb = this.table(trx).count({ count: this.key }) query ? query(qb) : qb.where(field, value) @@ -141,6 +164,12 @@ export class MysqlCache extends MysqlNative { return this.system + ':' + this.name + ':' + nsp.join(':') } + // 为每个事务维护独立的缓存空间 + protected getTransactionCacheNsp(trx?: CoaMysql.Transaction, ...nsp: string[]) { + const base = this.system + ':' + this.name + ':' + nsp.join(':') + return trx && (trx as any).id ? `${base}:trx:${(trx as any).id}` : base + } + protected async getCacheChangedDataList(ids: string[], data?: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { let has = true const resultList = [] as Array> @@ -155,7 +184,7 @@ export class MysqlCache extends MysqlNative { return resultList } - protected async deleteCache(ids: string[], dataList: Array>) { + async deleteCache(ids: string[], dataList: Array>) { const deleteIds = [] as CoaRedis.CacheDelete[] deleteIds.push([this.getCacheNsp('id'), ids]) deleteIds.push([this.getCacheNsp('data'), []]) @@ -173,5 +202,7 @@ export class MysqlCache extends MysqlNative { }) }) await this.redisCache.mDelete(deleteIds) + echo.grey(`REDIS:DeleteIds${deleteIds};`) + } } diff --git a/src/test/demo.ts b/src/test/demo.ts index 3e1c899..339b425 100644 --- a/src/test/demo.ts +++ b/src/test/demo.ts @@ -1,57 +1,37 @@ /* eslint-disable @typescript-eslint/no-redeclare */ // @ts-nocheck -import { CoaMysql, MysqlBin, MysqlNative } from '..' - +import { $, _ } from 'coa-helper' +import { RedisBin, RedisCache } from 'coa-redis' +import { MysqlBin, MysqlCache } from '..' // MySQL配置 const mysqlConfig = { host: '127.0.0.1', port: 3306, user: 'root', - password: 'root', + password: '19990728', charset: 'utf8mb4', trace: true, debug: false, databases: { - main: { database: 'test', ms: 7 * 24 * 3600 * 1000 }, - other: { database: 'other', ms: 7 * 24 * 3600 * 1000 }, + main: { database: 'mm-site-t1', ms: 7 * 24 * 3600 * 1000 }, }, } -// 初始化Mysql基本连接,后续所有模型均依赖此实例 -const mysqlBin = new MysqlBin(mysqlConfig) - -// 基本SQL操作 - -// 插入数据 https://knexjs.org/#Builder-insert -await mysqlBin.io.table('user').insert({ userId: 'user-a', name: 'A', mobile: '15010001001', gender: 1, language: 'zh-CN', status: 1 }) - -// 查询全部数据,详见 https://knexjs.org/#Builder-select -await mysqlBin.io.table('user').select() -await mysqlBin.io.select('*').from('user') - -// 带条件查询,详见 https://knexjs.org/#Builder-where -await mysqlBin.io.table('user').where('status', '=', 1) - -// 修改数据,详见 http://knexjs.org/#Builder-update -await mysqlBin.io.table('user').update({ name: 'AA', gender: 2 }).where({ userId: 'user-a' }) - -// 删除数据,详见 http://knexjs.org/#Builder-del%20/%20delete -await mysqlBin.io.table('user').delete().where({ userId: 'user-a' }) - -// 通过mysqlBin定义一个模型的基类,各个模型都可以使用这个基类 -export class MysqlNativeModel extends MysqlNative { - constructor(option: CoaMysql.ModelOption) { - // 将实例配置bin绑定 - super(option, mysqlBin) - } +const redisConfig = { + host: '127.0.0.1', + port: 6379, + password: '', + db: 1, + prefix: '', + trace: false, - // 也可以定义一些通用方法 - commonMethod() { - // do something - } } +const redisBin = new RedisBin(redisConfig) +const redisCache = new RedisCache(redisBin) + +// 初始化Mysql基本连接,后续所有模型均依赖此实例 +const mysqlBin = new MysqlBin(mysqlConfig) -// 定义User默认结构 const userScheme = { userId: '' as string, name: '' as string, @@ -63,11 +43,25 @@ const userScheme = { created: 0 as number, updated: 0 as number, } + +// const userScheme1 = { +// userId: '' as string, +// name: '' as string, +// mobile: '' as string, +// avatar: '' as string, +// gender: 1 as number, +// language: '' as string, +// status: 1 as number, +// created: 0 as number, +// updated: 0 as number, +// } + // 定义User类型(通过默认结构自动生成) type UserScheme = typeof userScheme + // 通过基类初始化 -const User = new (class extends MysqlNative { +const User = new (class extends MysqlCache { constructor() { super( { @@ -76,72 +70,44 @@ const User = new (class extends MysqlNative { scheme: userScheme, // 表的默认结构 pick: ['userId', 'name'], // 查询列表时显示的字段信息 }, - mysqlBin - ) // 绑定配置实例bin - } - - // 自定义方法 - async customMethod() { - // 做一些事情 + mysqlBin, + redisCache, + ) } })() -// 通过基类模型定义用户模型 -const User = new (class extends MysqlNativeModel { - constructor() { - super({ name: 'User', title: '用户表', scheme: userScheme, pick: ['userId', 'name'] }) - } - - // 自定义方法 - async customMethodForUser() { - // 做一些事情 - } -})() - -// 通过基类模型定义管理员模型 -const Manager = new (class extends MysqlNativeModel { - constructor() { - super({ name: 'Manager', title: '管理员表', scheme: userScheme, pick: ['userId', 'name'] }) - } -})() - -// 用户模型和管理员模型均可以调用公共方法 -await User.commonMethod() -await Manager.commonMethod() - -// 仅仅用户模型可以调用自定义方法 -await User.customMethodForUser() - -// 插入 -await User.insert({ name: '王小明', gender: 1 }) // 返回 'id001',即该条数据的 userId = 'id001' +// const User1 = new (class extends MysqlCache { +// constructor() { +// super( +// { +// name: 'User1', // 表名,默认会转化为下划线(snackCase)形式,如 User->user UserPhoto->user_photo +// title: '用户表', // 表的备注名称 +// scheme: userScheme1, // 表的默认结构 +// pick: ['userId', 'name'], // 查询列表时显示的字段信息 +// }, +// mysqlBin, +// redisCache, +// ) +// } +// })() // 批量插入 -await User.mInsert([ - { name: '王小明', gender: 1 }, - { name: '宋小华', gender: 1 }, -]) // 返回 ['id002','id003'] - -// 通过ID更新 -await User.updateById('id002', { name: '李四' }) // 返回 1 - -// 通过ID批量更新 -await User.updateByIds(['id002', 'id003'], { status: 2 }) // 返回 2 - -// 通过ID更新或插入(如果id存在就更新,如果不存在就插入) -await User.upsertById('id002', { name: '王小明', gender: 1 }) // 返回 1 ,更新了一条 userId = 'id02' 的数据 -await User.upsertById('id004', { name: '李四', gender: 1 }) // 返回 0 ,插入一条新数据,数据的 userId = 'id04' +// await User.mInsert([ +// { name: '王小明', gender: 1 }, +// { name: '宋小华', gender: 1 }, +// ]) + +// await User.updateById('id002', { name: '李四' }) // 返回 1 +const a = async () => { + await mysqlBin.safeTransaction(async (trx: CoaMysql.Transaction) => { + await User.updateById('41102319990728253X', { name: 'mmm' }, trx) + const q = await User.checkById('41102319990728253X', ['name'], trx) + console.log(q); + await $.timeout(3000) + await User.insert({ name: 'heyifan2', userId: `${_.now()}Y${123}` }, trx) + }) + const b = await User.checkById('41102319990728253X') + console.log(b); -// 通过ID删除多个 -await User.deleteByIds(['id003', 'id004']) // 返回 2 - -// 通过ID查询一个,第二个参数设置返回结果所包含的数据 -await User.getById('id001', ['name']) // 数据为{userId:'id001',name:'王小明',gender:1,status:1,...} 实际返回 {userId:'id001',name:'王小明'} - -// 通过ID获取多个 -await User.mGetByIds(['id001', 'id002'], ['name']) // 返回 {id001:{userId:'id001',name:'王小明'},id002:{userId:'id002',name:'李四'}} - -// 截断表 -await User.truncate() // 无返回值,主要不报错即成功截断整个表 - -// 自定义方法 -await User.customMethod() // 执行自定义方法 +} +a() From e09b9282f976a4ca9106f0b8baf3e9f604551bce Mon Sep 17 00:00:00 2001 From: ityifan <329686198@qq.com> Date: Fri, 19 Sep 2025 09:52:08 +0800 Subject: [PATCH 02/26] =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libs/MysqlBin.ts | 4 +--- src/services/MysqlCache.ts | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libs/MysqlBin.ts b/src/libs/MysqlBin.ts index 937e35e..1040c28 100644 --- a/src/libs/MysqlBin.ts +++ b/src/libs/MysqlBin.ts @@ -1,10 +1,9 @@ import { echo } from 'coa-echo' import { CoaError } from 'coa-error' +import { secure } from 'coa-secure' import { MysqlCache } from '../services/MysqlCache' import { CoaMysql } from '../typings' import { Knex } from './Knex' - -import { secure } from 'coa-secure' export class MysqlBin { public io: Knex public config: CoaMysql.Config @@ -41,7 +40,6 @@ export class MysqlBin { cacheTasks.push({ model, ids, dataList }) trx.id ||= secure.id25(`${Date.now()}-${model}`) } - return await handler(trx) }) diff --git a/src/services/MysqlCache.ts b/src/services/MysqlCache.ts index 199daf1..ee71f5d 100644 --- a/src/services/MysqlCache.ts +++ b/src/services/MysqlCache.ts @@ -17,7 +17,7 @@ export class MysqlCache extends MysqlNative { async insert(data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const id = await super.insert(data, trx) if (id) { - (trx && (trx as any).registerCacheClear) ? (trx as any).registerCacheClear(this, [id], data) : await this.deleteCache([id], [data]) + (trx && (trx as any).registerCacheClear) ? (trx as any).registerCacheClear(this, [id], [data]) : await this.deleteCache([id], [data]) } return id } From fb6773d23b22c30d3bc1c6167d6381e18cb350bb Mon Sep 17 00:00:00 2001 From: ityifan <329686198@qq.com> Date: Fri, 19 Sep 2025 13:32:33 +0800 Subject: [PATCH 03/26] =?UTF-8?q?=E5=88=A0=E9=99=A4=E4=BA=8B=E5=8A=A1id?= =?UTF-8?q?=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libs/MysqlBin.ts | 23 +++++++++++++++++------ src/services/MysqlCache.ts | 29 ++++++++++++++++------------- src/test/demo.ts | 11 +++++++---- 3 files changed, 40 insertions(+), 23 deletions(-) diff --git a/src/libs/MysqlBin.ts b/src/libs/MysqlBin.ts index 1040c28..dc45577 100644 --- a/src/libs/MysqlBin.ts +++ b/src/libs/MysqlBin.ts @@ -33,21 +33,32 @@ export class MysqlBin { } async safeTransaction(handler: (trx: CoaMysql.Transaction) => Promise): Promise { - let cacheTasks: Array<{ model: MysqlCache, ids: string[], dataList: any[] }> = [] + + let cacheTasks = { + trxUpdateCacheTaskList: [] as Array<{ model: MysqlCache, ids: string[], dataList: any[] }>, + trxRaeadCacheNspsList: [] as Array<{ model: MysqlCache, nsp: string }> + }; const result = await this.io.transaction(async (trx: any) => { - trx.registerCacheClear = (model: MysqlCache, ids: string[], dataList: any[]) => { - cacheTasks.push({ model, ids, dataList }) - trx.id ||= secure.id25(`${Date.now()}-${model}`) + trx.id ||= secure.id25(`${Date.now()}-${Math.floor(Math.random() * 1e6).toString().padStart(6, '0')}`) + trx.trxUpdateCacheTaskList = (model: MysqlCache, ids: string[], dataList: any[]) => { + cacheTasks.trxUpdateCacheTaskList.push({ model, ids, dataList }) + } + trx.trxRaeadCacheNspsList = (model: MysqlCache, nsp: string) => { + cacheTasks.trxRaeadCacheNspsList.push({ model, nsp }) } return await handler(trx) }) - for (const task of cacheTasks) { + for (const task of cacheTasks.trxUpdateCacheTaskList) { await task.model.deleteCache(task.ids, task.dataList) } + + for (const readCacheNsp of cacheTasks.trxRaeadCacheNspsList) { + await readCacheNsp.model.redisCache.clear(readCacheNsp.nsp) + } // 初始数组 减少trx未及时销毁时的内存占用 - cacheTasks = [] + cacheTasks = { trxUpdateCacheTaskList: [], trxRaeadCacheNspsList: [] } return result } diff --git a/src/services/MysqlCache.ts b/src/services/MysqlCache.ts index ee71f5d..cbe7c08 100644 --- a/src/services/MysqlCache.ts +++ b/src/services/MysqlCache.ts @@ -17,7 +17,7 @@ export class MysqlCache extends MysqlNative { async insert(data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const id = await super.insert(data, trx) if (id) { - (trx && (trx as any).registerCacheClear) ? (trx as any).registerCacheClear(this, [id], [data]) : await this.deleteCache([id], [data]) + (trx && (trx as any).trxUpdateCacheTaskList) ? (trx as any).trxUpdateCacheTaskList(this, [id], [data]) : await this.deleteCache([id], [data]) } return id } @@ -25,7 +25,7 @@ export class MysqlCache extends MysqlNative { async mInsert(dataList: Array>, trx?: CoaMysql.Transaction) { const ids = await super.mInsert(dataList, trx) if (ids) { - (trx && (trx as any).registerCacheClear) ? (trx as any).registerCacheClear(this, ids, dataList) : await this.deleteCache(ids, dataList) + (trx && (trx as any).trxUpdateCacheTaskList) ? (trx as any).trxUpdateCacheTaskList(this, ids, dataList) : await this.deleteCache(ids, dataList) } return ids } @@ -34,7 +34,7 @@ export class MysqlCache extends MysqlNative { const dataList = await this.getCacheChangedDataList([id], data, trx) const result = await super.updateById(id, data, trx) if (result) { - (trx && (trx as any).registerCacheClear) ? (trx as any).registerCacheClear(this, [id], dataList) : await this.deleteCache([id], dataList) + (trx && (trx as any).trxUpdateCacheTaskList) ? (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) } return result } @@ -43,7 +43,7 @@ export class MysqlCache extends MysqlNative { const dataList = await this.getCacheChangedDataList(ids, data, trx) const result = await super.updateByIds(ids, data, trx) if (result) { - (trx && (trx as any).registerCacheClear) ? (trx as any).registerCacheClear(this, ids, dataList) : await this.deleteCache(ids, dataList) + (trx && (trx as any).trxUpdateCacheTaskList) ? (trx as any).trxUpdateCacheTaskList(this, ids, dataList) : await this.deleteCache(ids, dataList) } return result } @@ -52,7 +52,7 @@ export class MysqlCache extends MysqlNative { const dataList = await this.getCacheChangedDataList([id], data, trx) const result = await super.updateForQueryById(id, query, data, trx) if (result) { - (trx && (trx as any).registerCacheClear) ? (trx as any).registerCacheClear(this, [id], dataList) : await this.deleteCache([id], dataList) + (trx && (trx as any).trxUpdateCacheTaskList) ? (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) } return result } @@ -61,7 +61,7 @@ export class MysqlCache extends MysqlNative { const dataList = await this.getCacheChangedDataList([id], data, trx) const result = await super.upsertById(id, data, trx) if (result) { - (trx && (trx as any).registerCacheClear) ? (trx as any).registerCacheClear(this, [id], dataList) : await this.deleteCache([id], dataList) + (trx && (trx as any).trxUpdateCacheTaskList) ? (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) } return result } @@ -70,7 +70,7 @@ export class MysqlCache extends MysqlNative { const dataList = await this.getCacheChangedDataList(ids, undefined, trx) const result = await super.deleteByIds(ids, trx) if (result) { - (trx && (trx as any).registerCacheClear) ? (trx as any).registerCacheClear(this, ids, dataList) : await this.deleteCache(ids, dataList) + (trx && (trx as any).trxUpdateCacheTaskList) ? (trx as any).trxUpdateCacheTaskList(this, ids, dataList) : await this.deleteCache(ids, dataList) } return result } @@ -81,17 +81,20 @@ export class MysqlCache extends MysqlNative { async getById(id: string, pick = this.columns, trx?: CoaMysql.Transaction, ms = this.ms, force = false) { const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'id') : this.getCacheNsp('id') + trx && (trx as any).trxRaeadCacheNspsList(this, cacheNsp) const result = await this.redisCache.warp(cacheNsp, id, async () => await super.getById(id, this.columns, trx), ms, force) return this.pickResult(result, pick) } async getIdBy(field: string, value: string | number, trx?: CoaMysql.Transaction) { const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'index', field) : this.getCacheNsp('index', field) + trx && (trx as any).trxRaeadCacheNspsList(this, cacheNsp) return await this.redisCache.warp(cacheNsp, '' + value, async () => await super.getIdBy(field, value, trx)) } async mGetByIds(ids: string[], pick = this.pick, trx?: CoaMysql.Transaction, ms = this.ms, force = false) { const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'id') : this.getCacheNsp('id') + trx && (trx as any).trxRaeadCacheNspsList(this, cacheNsp) const result = await this.redisCache.mWarp(cacheNsp, ids, async ids => await super.mGetByIds(ids, this.columns, trx), ms, force) _.forEach(result, (v, k) => { result[k] = this.pickResult(v, pick) @@ -105,37 +108,37 @@ export class MysqlCache extends MysqlNative { } protected async findListCount(finger: Array>, query: CoaMysql.Query, trx?: CoaMysql.Transaction) { - // const cacheNsp = this.getCacheNsp('data') const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'data') : this.getCacheNsp('data') + trx && (trx as any).trxRaeadCacheNspsList(this, cacheNsp) const cacheId = 'list-count:' + secure.sha1($.sortQueryString(...finger)) return await this.redisCache.warp(cacheNsp, cacheId, async () => await super.selectListCount(query, trx)) } protected async findIdList(finger: Array>, query: CoaMysql.Query, trx?: CoaMysql.Transaction) { - // const cacheNsp = this.getCacheNsp('data') const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'data') : this.getCacheNsp('data') + trx && (trx as any).trxRaeadCacheNspsList(this, cacheNsp) const cacheId = 'list:' + secure.sha1($.sortQueryString(...finger)) return await this.redisCache.warp(cacheNsp, cacheId, async () => await super.selectIdList(query, trx)) } protected async findIdSortList(finger: Array>, pager: CoaMysql.Pager, query: CoaMysql.Query, trx?: CoaMysql.Transaction) { - // const cacheNsp = this.getCacheNsp('data') const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'data') : this.getCacheNsp('data') + trx && (trx as any).trxRaeadCacheNspsList(this, cacheNsp) const cacheId = `sort-list:${pager.rows}:${pager.last}:` + secure.sha1($.sortQueryString(...finger)) return await this.redisCache.warp(cacheNsp, cacheId, async () => await super.selectIdSortList(pager, query, trx)) } protected async findIdViewList(finger: Array>, pager: CoaMysql.Pager, query: CoaMysql.Query, trx?: CoaMysql.Transaction) { - // const cacheNsp = this.getCacheNsp('data') const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'data') : this.getCacheNsp('data') + trx && (trx as any).trxRaeadCacheNspsList(this, cacheNsp) const cacheId = `view-list:${pager.rows}:${pager.page}:` + secure.sha1($.sortQueryString(...finger)) const count = await this.findListCount(finger, query, trx) return await this.redisCache.warp(cacheNsp, cacheId, async () => await super.selectIdViewList(pager, query, trx, count)) } protected async mGetCountBy(field: string, ids: string[], trx?: CoaMysql.Transaction) { - // const cacheNsp = this.getCacheNsp('count', field) const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'count', field) : this.getCacheNsp('count', field) + trx && (trx as any).trxRaeadCacheNspsList(this, cacheNsp) return await this.redisCache.mWarp(cacheNsp, ids, async ids => { const rows = (await this.table(trx).select({ id: field }).count({ count: this.key }).whereIn(field, ids).groupBy(field)) as any[] const result: CoaMysql.Dic = {} @@ -145,8 +148,8 @@ export class MysqlCache extends MysqlNative { } protected async getCountBy(field: string, value: string, query?: CoaMysql.Query, trx?: CoaMysql.Transaction) { - // const cacheNsp = this.getCacheNsp('count', field) const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'count', field) : this.getCacheNsp('count', field) + trx && (trx as any).trxRaeadCacheNspsList(this, cacheNsp) return await this.redisCache.warp(cacheNsp, value, async () => { const qb = this.table(trx).count({ count: this.key }) query ? query(qb) : qb.where(field, value) diff --git a/src/test/demo.ts b/src/test/demo.ts index 339b425..a9a799d 100644 --- a/src/test/demo.ts +++ b/src/test/demo.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-redeclare */ // @ts-nocheck -import { $, _ } from 'coa-helper' +import { $ } from 'coa-helper' import { RedisBin, RedisCache } from 'coa-redis' import { MysqlBin, MysqlCache } from '..' // MySQL配置 @@ -101,13 +101,16 @@ const User = new (class extends MysqlCache { const a = async () => { await mysqlBin.safeTransaction(async (trx: CoaMysql.Transaction) => { await User.updateById('41102319990728253X', { name: 'mmm' }, trx) - const q = await User.checkById('41102319990728253X', ['name'], trx) + const q = await User.checkById('41102319990728253X', Object.keys(userScheme), trx) console.log(q); await $.timeout(3000) - await User.insert({ name: 'heyifan2', userId: `${_.now()}Y${123}` }, trx) + await User.updateById('1758003943672Y2', { name: 'heyifan2' }, trx) }) const b = await User.checkById('41102319990728253X') console.log(b); - + // const id = await redisCache.clearUseless('*id') + // console.log('cRedis: ID类型过期缓存清除成功', id) + // const data = await redisCache.clearUseless('*data') + // console.log('cRedis: DATA类型过期缓存清除成功', data) } a() From 87f5274c212202e1c0938f7f7cd010a0177696ea Mon Sep 17 00:00:00 2001 From: ityifan <329686198@qq.com> Date: Fri, 19 Sep 2025 16:13:56 +0800 Subject: [PATCH 04/26] =?UTF-8?q?=E5=88=A0=E9=99=A4=E4=BA=8B=E5=8A=A1?= =?UTF-8?q?=E8=B5=B0=E7=BC=93=E5=AD=98=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libs/MysqlBin.ts | 22 ++++------- src/services/MysqlCache.ts | 75 +++++++++++++++++--------------------- src/test/demo.ts | 13 ++++--- 3 files changed, 49 insertions(+), 61 deletions(-) diff --git a/src/libs/MysqlBin.ts b/src/libs/MysqlBin.ts index dc45577..f56852a 100644 --- a/src/libs/MysqlBin.ts +++ b/src/libs/MysqlBin.ts @@ -34,31 +34,23 @@ export class MysqlBin { async safeTransaction(handler: (trx: CoaMysql.Transaction) => Promise): Promise { - let cacheTasks = { - trxUpdateCacheTaskList: [] as Array<{ model: MysqlCache, ids: string[], dataList: any[] }>, - trxRaeadCacheNspsList: [] as Array<{ model: MysqlCache, nsp: string }> - }; + let cacheTasks = [] as Array<{ model: MysqlCache, ids: string[], dataList: any[] }> const result = await this.io.transaction(async (trx: any) => { trx.id ||= secure.id25(`${Date.now()}-${Math.floor(Math.random() * 1e6).toString().padStart(6, '0')}`) - trx.trxUpdateCacheTaskList = (model: MysqlCache, ids: string[], dataList: any[]) => { - cacheTasks.trxUpdateCacheTaskList.push({ model, ids, dataList }) - } - trx.trxRaeadCacheNspsList = (model: MysqlCache, nsp: string) => { - cacheTasks.trxRaeadCacheNspsList.push({ model, nsp }) + // 收集事务更新缓存数据 + trx.trxUpdateCacheTaskList = async (model: MysqlCache, ids: string[], dataList: any[]) => { + cacheTasks.push({ model, ids, dataList }) } return await handler(trx) }) - - for (const task of cacheTasks.trxUpdateCacheTaskList) { + // 统一清理事务更新缓存 + for (const task of cacheTasks) { await task.model.deleteCache(task.ids, task.dataList) } - for (const readCacheNsp of cacheTasks.trxRaeadCacheNspsList) { - await readCacheNsp.model.redisCache.clear(readCacheNsp.nsp) - } // 初始数组 减少trx未及时销毁时的内存占用 - cacheTasks = { trxUpdateCacheTaskList: [], trxRaeadCacheNspsList: [] } + cacheTasks = [] return result } diff --git a/src/services/MysqlCache.ts b/src/services/MysqlCache.ts index cbe7c08..0ace369 100644 --- a/src/services/MysqlCache.ts +++ b/src/services/MysqlCache.ts @@ -16,53 +16,41 @@ export class MysqlCache extends MysqlNative { async insert(data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const id = await super.insert(data, trx) - if (id) { - (trx && (trx as any).trxUpdateCacheTaskList) ? (trx as any).trxUpdateCacheTaskList(this, [id], [data]) : await this.deleteCache([id], [data]) - } + trx && (trx as any).trxUpdateCacheTaskList ? await (trx as any).trxUpdateCacheTaskList(this, [id], [data]) : await this.deleteCache([id], [data]) return id } async mInsert(dataList: Array>, trx?: CoaMysql.Transaction) { const ids = await super.mInsert(dataList, trx) - if (ids) { - (trx && (trx as any).trxUpdateCacheTaskList) ? (trx as any).trxUpdateCacheTaskList(this, ids, dataList) : await this.deleteCache(ids, dataList) - } + trx && (trx as any).trxUpdateCacheTaskList ? await (trx as any).trxUpdateCacheTaskList(this, ids, dataList) : await this.deleteCache(ids, dataList) return ids } async updateById(id: string, data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList([id], data, trx) const result = await super.updateById(id, data, trx) - if (result) { - (trx && (trx as any).trxUpdateCacheTaskList) ? (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) - } + trx && (trx as any).trxUpdateCacheTaskList ? await (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) return result } async updateByIds(ids: string[], data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList(ids, data, trx) const result = await super.updateByIds(ids, data, trx) - if (result) { - (trx && (trx as any).trxUpdateCacheTaskList) ? (trx as any).trxUpdateCacheTaskList(this, ids, dataList) : await this.deleteCache(ids, dataList) - } + trx && (trx as any).trxUpdateCacheTaskList ? await (trx as any).trxUpdateCacheTaskList(this, ids, dataList) : await this.deleteCache(ids, dataList) return result } async updateForQueryById(id: string, query: CoaMysql.Query, data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList([id], data, trx) const result = await super.updateForQueryById(id, query, data, trx) - if (result) { - (trx && (trx as any).trxUpdateCacheTaskList) ? (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) - } + trx && (trx as any).trxUpdateCacheTaskList ? await (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) return result } async upsertById(id: string, data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList([id], data, trx) const result = await super.upsertById(id, data, trx) - if (result) { - (trx && (trx as any).trxUpdateCacheTaskList) ? (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) - } + trx && (trx as any).trxUpdateCacheTaskList ? await (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) return result } @@ -70,7 +58,7 @@ export class MysqlCache extends MysqlNative { const dataList = await this.getCacheChangedDataList(ids, undefined, trx) const result = await super.deleteByIds(ids, trx) if (result) { - (trx && (trx as any).trxUpdateCacheTaskList) ? (trx as any).trxUpdateCacheTaskList(this, ids, dataList) : await this.deleteCache(ids, dataList) + (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, ids, dataList) : await this.deleteCache(ids, dataList) } return result } @@ -81,21 +69,18 @@ export class MysqlCache extends MysqlNative { async getById(id: string, pick = this.columns, trx?: CoaMysql.Transaction, ms = this.ms, force = false) { const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'id') : this.getCacheNsp('id') - trx && (trx as any).trxRaeadCacheNspsList(this, cacheNsp) - const result = await this.redisCache.warp(cacheNsp, id, async () => await super.getById(id, this.columns, trx), ms, force) + const result = trx ? await super.getById(id, this.columns, trx) : await this.redisCache.warp(cacheNsp, id, async () => await super.getById(id, this.columns, trx), ms, force) return this.pickResult(result, pick) } async getIdBy(field: string, value: string | number, trx?: CoaMysql.Transaction) { const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'index', field) : this.getCacheNsp('index', field) - trx && (trx as any).trxRaeadCacheNspsList(this, cacheNsp) - return await this.redisCache.warp(cacheNsp, '' + value, async () => await super.getIdBy(field, value, trx)) + return trx ? await super.getIdBy(field, value, trx) : await this.redisCache.warp(cacheNsp, '' + value, async () => await super.getIdBy(field, value, trx)) } async mGetByIds(ids: string[], pick = this.pick, trx?: CoaMysql.Transaction, ms = this.ms, force = false) { const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'id') : this.getCacheNsp('id') - trx && (trx as any).trxRaeadCacheNspsList(this, cacheNsp) - const result = await this.redisCache.mWarp(cacheNsp, ids, async ids => await super.mGetByIds(ids, this.columns, trx), ms, force) + const result = trx ? await super.mGetByIds(ids, this.columns, trx) : await this.redisCache.mWarp(cacheNsp, ids, async ids => await super.mGetByIds(ids, this.columns, trx), ms, force) _.forEach(result, (v, k) => { result[k] = this.pickResult(v, pick) }) @@ -109,53 +94,61 @@ export class MysqlCache extends MysqlNative { protected async findListCount(finger: Array>, query: CoaMysql.Query, trx?: CoaMysql.Transaction) { const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'data') : this.getCacheNsp('data') - trx && (trx as any).trxRaeadCacheNspsList(this, cacheNsp) const cacheId = 'list-count:' + secure.sha1($.sortQueryString(...finger)) - return await this.redisCache.warp(cacheNsp, cacheId, async () => await super.selectListCount(query, trx)) + return trx ? await super.selectListCount(query, trx) : await this.redisCache.warp(cacheNsp, cacheId, async () => await super.selectListCount(query, trx)) } protected async findIdList(finger: Array>, query: CoaMysql.Query, trx?: CoaMysql.Transaction) { const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'data') : this.getCacheNsp('data') - trx && (trx as any).trxRaeadCacheNspsList(this, cacheNsp) const cacheId = 'list:' + secure.sha1($.sortQueryString(...finger)) - return await this.redisCache.warp(cacheNsp, cacheId, async () => await super.selectIdList(query, trx)) + return trx ? await super.selectIdList(query, trx) : await this.redisCache.warp(cacheNsp, cacheId, async () => await super.selectIdList(query, trx)) } protected async findIdSortList(finger: Array>, pager: CoaMysql.Pager, query: CoaMysql.Query, trx?: CoaMysql.Transaction) { const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'data') : this.getCacheNsp('data') - trx && (trx as any).trxRaeadCacheNspsList(this, cacheNsp) const cacheId = `sort-list:${pager.rows}:${pager.last}:` + secure.sha1($.sortQueryString(...finger)) - return await this.redisCache.warp(cacheNsp, cacheId, async () => await super.selectIdSortList(pager, query, trx)) + return trx ? await super.selectIdSortList(pager, query, trx) : await this.redisCache.warp(cacheNsp, cacheId, async () => await super.selectIdSortList(pager, query, trx)) } protected async findIdViewList(finger: Array>, pager: CoaMysql.Pager, query: CoaMysql.Query, trx?: CoaMysql.Transaction) { const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'data') : this.getCacheNsp('data') - trx && (trx as any).trxRaeadCacheNspsList(this, cacheNsp) const cacheId = `view-list:${pager.rows}:${pager.page}:` + secure.sha1($.sortQueryString(...finger)) const count = await this.findListCount(finger, query, trx) - return await this.redisCache.warp(cacheNsp, cacheId, async () => await super.selectIdViewList(pager, query, trx, count)) + return trx ? await super.selectIdViewList(pager, query, trx, count) : await this.redisCache.warp(cacheNsp, cacheId, async () => await super.selectIdViewList(pager, query, trx, count)) } protected async mGetCountBy(field: string, ids: string[], trx?: CoaMysql.Transaction) { - const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'count', field) : this.getCacheNsp('count', field) - trx && (trx as any).trxRaeadCacheNspsList(this, cacheNsp) - return await this.redisCache.mWarp(cacheNsp, ids, async ids => { + const queryFunction = async () => { const rows = (await this.table(trx).select({ id: field }).count({ count: this.key }).whereIn(field, ids).groupBy(field)) as any[] const result: CoaMysql.Dic = {} _.forEach(rows, ({ id, count }) => (result[id] = count)) return result - }) + } + + if (trx) { + return await queryFunction() + } else { + const cacheNsp = this.getCacheNsp('count', field) + return await this.redisCache.mWarp(cacheNsp, ids, queryFunction) + } } protected async getCountBy(field: string, value: string, query?: CoaMysql.Query, trx?: CoaMysql.Transaction) { - const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'count', field) : this.getCacheNsp('count', field) - trx && (trx as any).trxRaeadCacheNspsList(this, cacheNsp) - return await this.redisCache.warp(cacheNsp, value, async () => { + const queryFunction = async () => { const qb = this.table(trx).count({ count: this.key }) query ? query(qb) : qb.where(field, value) const rows = await qb return (rows[0]?.count as number) || 0 - }) + } + + if (trx) { + // 事务内直接查询数据库,不走缓存 + return await queryFunction() + } else { + // 非事务走缓存 + const cacheNsp = this.getCacheNsp('count', field) + return await this.redisCache.warp(cacheNsp, value, queryFunction) + } } protected pickResult(data: T, pick: string[]) { diff --git a/src/test/demo.ts b/src/test/demo.ts index a9a799d..3f7d6c9 100644 --- a/src/test/demo.ts +++ b/src/test/demo.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-redeclare */ // @ts-nocheck -import { $ } from 'coa-helper' +import { $, _ } from 'coa-helper' import { RedisBin, RedisCache } from 'coa-redis' import { MysqlBin, MysqlCache } from '..' // MySQL配置 @@ -69,6 +69,7 @@ const User = new (class extends MysqlCache { title: '用户表', // 表的备注名称 scheme: userScheme, // 表的默认结构 pick: ['userId', 'name'], // 查询列表时显示的字段信息 + caches: { index: ['name'], count: ['userId', 'name'] } }, mysqlBin, redisCache, @@ -99,12 +100,14 @@ const User = new (class extends MysqlCache { // await User.updateById('id002', { name: '李四' }) // 返回 1 const a = async () => { + await User.checkById('41102319990728253X') await mysqlBin.safeTransaction(async (trx: CoaMysql.Transaction) => { await User.updateById('41102319990728253X', { name: 'mmm' }, trx) - const q = await User.checkById('41102319990728253X', Object.keys(userScheme), trx) - console.log(q); - await $.timeout(3000) - await User.updateById('1758003943672Y2', { name: 'heyifan2' }, trx) + for (let index = 0; index < 10; index++) { + const userId = `${_.now()}-${index}-Y` + await $.timeout(3000) + await User.insert({ userId, name: 'heyifan2' }, trx) + } }) const b = await User.checkById('41102319990728253X') console.log(b); From b013f806a99055951c40c5e056fcc71aa738ea92 Mon Sep 17 00:00:00 2001 From: ityifan <329686198@qq.com> Date: Fri, 19 Sep 2025 16:25:08 +0800 Subject: [PATCH 05/26] =?UTF-8?q?=E6=9A=82=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/MysqlCache.ts | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/src/services/MysqlCache.ts b/src/services/MysqlCache.ts index 0ace369..ce13055 100644 --- a/src/services/MysqlCache.ts +++ b/src/services/MysqlCache.ts @@ -68,19 +68,16 @@ export class MysqlCache extends MysqlNative { } async getById(id: string, pick = this.columns, trx?: CoaMysql.Transaction, ms = this.ms, force = false) { - const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'id') : this.getCacheNsp('id') - const result = trx ? await super.getById(id, this.columns, trx) : await this.redisCache.warp(cacheNsp, id, async () => await super.getById(id, this.columns, trx), ms, force) + const result = trx ? await super.getById(id, this.columns, trx) : await this.redisCache.warp(this.getCacheNsp('id'), id, async () => await super.getById(id, this.columns, trx), ms, force) return this.pickResult(result, pick) } async getIdBy(field: string, value: string | number, trx?: CoaMysql.Transaction) { - const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'index', field) : this.getCacheNsp('index', field) - return trx ? await super.getIdBy(field, value, trx) : await this.redisCache.warp(cacheNsp, '' + value, async () => await super.getIdBy(field, value, trx)) + return trx ? await super.getIdBy(field, value, trx) : await this.redisCache.warp(this.getCacheNsp('index', field), '' + value, async () => await super.getIdBy(field, value, trx)) } async mGetByIds(ids: string[], pick = this.pick, trx?: CoaMysql.Transaction, ms = this.ms, force = false) { - const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'id') : this.getCacheNsp('id') - const result = trx ? await super.mGetByIds(ids, this.columns, trx) : await this.redisCache.mWarp(cacheNsp, ids, async ids => await super.mGetByIds(ids, this.columns, trx), ms, force) + const result = trx ? await super.mGetByIds(ids, this.columns, trx) : await this.redisCache.mWarp(this.getCacheNsp('id'), ids, async ids => await super.mGetByIds(ids, this.columns, trx), ms, force) _.forEach(result, (v, k) => { result[k] = this.pickResult(v, pick) }) @@ -93,28 +90,24 @@ export class MysqlCache extends MysqlNative { } protected async findListCount(finger: Array>, query: CoaMysql.Query, trx?: CoaMysql.Transaction) { - const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'data') : this.getCacheNsp('data') const cacheId = 'list-count:' + secure.sha1($.sortQueryString(...finger)) - return trx ? await super.selectListCount(query, trx) : await this.redisCache.warp(cacheNsp, cacheId, async () => await super.selectListCount(query, trx)) + return trx ? await super.selectListCount(query, trx) : await this.redisCache.warp(this.getCacheNsp('data'), cacheId, async () => await super.selectListCount(query, trx)) } protected async findIdList(finger: Array>, query: CoaMysql.Query, trx?: CoaMysql.Transaction) { - const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'data') : this.getCacheNsp('data') const cacheId = 'list:' + secure.sha1($.sortQueryString(...finger)) - return trx ? await super.selectIdList(query, trx) : await this.redisCache.warp(cacheNsp, cacheId, async () => await super.selectIdList(query, trx)) + return trx ? await super.selectIdList(query, trx) : await this.redisCache.warp(this.getCacheNsp('data'), cacheId, async () => await super.selectIdList(query, trx)) } protected async findIdSortList(finger: Array>, pager: CoaMysql.Pager, query: CoaMysql.Query, trx?: CoaMysql.Transaction) { - const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'data') : this.getCacheNsp('data') const cacheId = `sort-list:${pager.rows}:${pager.last}:` + secure.sha1($.sortQueryString(...finger)) - return trx ? await super.selectIdSortList(pager, query, trx) : await this.redisCache.warp(cacheNsp, cacheId, async () => await super.selectIdSortList(pager, query, trx)) + return trx ? await super.selectIdSortList(pager, query, trx) : await this.redisCache.warp(this.getCacheNsp('data'), cacheId, async () => await super.selectIdSortList(pager, query, trx)) } protected async findIdViewList(finger: Array>, pager: CoaMysql.Pager, query: CoaMysql.Query, trx?: CoaMysql.Transaction) { - const cacheNsp = trx ? this.getTransactionCacheNsp(trx, 'data') : this.getCacheNsp('data') const cacheId = `view-list:${pager.rows}:${pager.page}:` + secure.sha1($.sortQueryString(...finger)) const count = await this.findListCount(finger, query, trx) - return trx ? await super.selectIdViewList(pager, query, trx, count) : await this.redisCache.warp(cacheNsp, cacheId, async () => await super.selectIdViewList(pager, query, trx, count)) + return trx ? await super.selectIdViewList(pager, query, trx, count) : await this.redisCache.warp(this.getCacheNsp('data'), cacheId, async () => await super.selectIdViewList(pager, query, trx, count)) } protected async mGetCountBy(field: string, ids: string[], trx?: CoaMysql.Transaction) { @@ -128,8 +121,7 @@ export class MysqlCache extends MysqlNative { if (trx) { return await queryFunction() } else { - const cacheNsp = this.getCacheNsp('count', field) - return await this.redisCache.mWarp(cacheNsp, ids, queryFunction) + return await this.redisCache.mWarp(this.getCacheNsp('count', field), ids, queryFunction) } } @@ -146,8 +138,7 @@ export class MysqlCache extends MysqlNative { return await queryFunction() } else { // 非事务走缓存 - const cacheNsp = this.getCacheNsp('count', field) - return await this.redisCache.warp(cacheNsp, value, queryFunction) + return await this.redisCache.warp(this.getCacheNsp('count', field), value, queryFunction) } } @@ -160,12 +151,6 @@ export class MysqlCache extends MysqlNative { return this.system + ':' + this.name + ':' + nsp.join(':') } - // 为每个事务维护独立的缓存空间 - protected getTransactionCacheNsp(trx?: CoaMysql.Transaction, ...nsp: string[]) { - const base = this.system + ':' + this.name + ':' + nsp.join(':') - return trx && (trx as any).id ? `${base}:trx:${(trx as any).id}` : base - } - protected async getCacheChangedDataList(ids: string[], data?: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { let has = true const resultList = [] as Array> From db98282da97a344eae5dfa4cad844054c5233150 Mon Sep 17 00:00:00 2001 From: ityifan <329686198@qq.com> Date: Fri, 19 Sep 2025 16:51:57 +0800 Subject: [PATCH 06/26] =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/MysqlCache.ts | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/src/services/MysqlCache.ts b/src/services/MysqlCache.ts index ce13055..c656bcc 100644 --- a/src/services/MysqlCache.ts +++ b/src/services/MysqlCache.ts @@ -15,51 +15,49 @@ export class MysqlCache extends MysqlNative { } async insert(data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { - const id = await super.insert(data, trx) + const id = await super.insert(data, trx); trx && (trx as any).trxUpdateCacheTaskList ? await (trx as any).trxUpdateCacheTaskList(this, [id], [data]) : await this.deleteCache([id], [data]) return id } async mInsert(dataList: Array>, trx?: CoaMysql.Transaction) { - const ids = await super.mInsert(dataList, trx) + const ids = await super.mInsert(dataList, trx); trx && (trx as any).trxUpdateCacheTaskList ? await (trx as any).trxUpdateCacheTaskList(this, ids, dataList) : await this.deleteCache(ids, dataList) return ids } async updateById(id: string, data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList([id], data, trx) - const result = await super.updateById(id, data, trx) + const result = await super.updateById(id, data, trx); trx && (trx as any).trxUpdateCacheTaskList ? await (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) return result } async updateByIds(ids: string[], data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList(ids, data, trx) - const result = await super.updateByIds(ids, data, trx) + const result = await super.updateByIds(ids, data, trx); trx && (trx as any).trxUpdateCacheTaskList ? await (trx as any).trxUpdateCacheTaskList(this, ids, dataList) : await this.deleteCache(ids, dataList) return result } async updateForQueryById(id: string, query: CoaMysql.Query, data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList([id], data, trx) - const result = await super.updateForQueryById(id, query, data, trx) + const result = await super.updateForQueryById(id, query, data, trx); trx && (trx as any).trxUpdateCacheTaskList ? await (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) return result } async upsertById(id: string, data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList([id], data, trx) - const result = await super.upsertById(id, data, trx) + const result = await super.upsertById(id, data, trx); trx && (trx as any).trxUpdateCacheTaskList ? await (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) return result } async deleteByIds(ids: string[], trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList(ids, undefined, trx) - const result = await super.deleteByIds(ids, trx) - if (result) { - (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, ids, dataList) : await this.deleteCache(ids, dataList) - } + const result = await super.deleteByIds(ids, trx); + trx && (trx as any).trxUpdateCacheTaskList ? await (trx as any).trxUpdateCacheTaskList(this, ids, dataList) : await this.deleteCache(ids, dataList) return result } @@ -117,12 +115,8 @@ export class MysqlCache extends MysqlNative { _.forEach(rows, ({ id, count }) => (result[id] = count)) return result } - - if (trx) { - return await queryFunction() - } else { - return await this.redisCache.mWarp(this.getCacheNsp('count', field), ids, queryFunction) - } + const result = trx ? await queryFunction() : await this.redisCache.mWarp(this.getCacheNsp('count', field), ids, queryFunction) + return result } protected async getCountBy(field: string, value: string, query?: CoaMysql.Query, trx?: CoaMysql.Transaction) { @@ -132,14 +126,8 @@ export class MysqlCache extends MysqlNative { const rows = await qb return (rows[0]?.count as number) || 0 } - - if (trx) { - // 事务内直接查询数据库,不走缓存 - return await queryFunction() - } else { - // 非事务走缓存 - return await this.redisCache.warp(this.getCacheNsp('count', field), value, queryFunction) - } + const result = trx ? await queryFunction() : await this.redisCache.warp(this.getCacheNsp('count', field), value, queryFunction) + return result } protected pickResult(data: T, pick: string[]) { From 028c30afba0044efd8e4ab56b4b4110d02a736db Mon Sep 17 00:00:00 2001 From: ityifan <329686198@qq.com> Date: Fri, 19 Sep 2025 16:54:49 +0800 Subject: [PATCH 07/26] =?UTF-8?q?=E5=88=A0=E9=99=A4=E8=BE=93=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/MysqlCache.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/services/MysqlCache.ts b/src/services/MysqlCache.ts index c656bcc..4310f11 100644 --- a/src/services/MysqlCache.ts +++ b/src/services/MysqlCache.ts @@ -1,4 +1,3 @@ -import { echo } from 'coa-echo' import { CoaError } from 'coa-error' import { $, _ } from 'coa-helper' import { CoaRedis, RedisCache } from 'coa-redis' @@ -171,7 +170,5 @@ export class MysqlCache extends MysqlNative { }) }) await this.redisCache.mDelete(deleteIds) - echo.grey(`REDIS:DeleteIds${deleteIds};`) - } } From 5058a4a22be5261e21d276271e02be01b04f7f24 Mon Sep 17 00:00:00 2001 From: ityifan <329686198@qq.com> Date: Fri, 19 Sep 2025 16:59:30 +0800 Subject: [PATCH 08/26] =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/MysqlCache.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/services/MysqlCache.ts b/src/services/MysqlCache.ts index 4310f11..a4a7c59 100644 --- a/src/services/MysqlCache.ts +++ b/src/services/MysqlCache.ts @@ -15,48 +15,48 @@ export class MysqlCache extends MysqlNative { async insert(data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const id = await super.insert(data, trx); - trx && (trx as any).trxUpdateCacheTaskList ? await (trx as any).trxUpdateCacheTaskList(this, [id], [data]) : await this.deleteCache([id], [data]) + (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, [id], [data]) : await this.deleteCache([id], [data]) return id } async mInsert(dataList: Array>, trx?: CoaMysql.Transaction) { const ids = await super.mInsert(dataList, trx); - trx && (trx as any).trxUpdateCacheTaskList ? await (trx as any).trxUpdateCacheTaskList(this, ids, dataList) : await this.deleteCache(ids, dataList) + (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, ids, dataList) : await this.deleteCache(ids, dataList) return ids } async updateById(id: string, data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList([id], data, trx) const result = await super.updateById(id, data, trx); - trx && (trx as any).trxUpdateCacheTaskList ? await (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) + (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) return result } async updateByIds(ids: string[], data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList(ids, data, trx) const result = await super.updateByIds(ids, data, trx); - trx && (trx as any).trxUpdateCacheTaskList ? await (trx as any).trxUpdateCacheTaskList(this, ids, dataList) : await this.deleteCache(ids, dataList) + (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, ids, dataList) : await this.deleteCache(ids, dataList) return result } async updateForQueryById(id: string, query: CoaMysql.Query, data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList([id], data, trx) const result = await super.updateForQueryById(id, query, data, trx); - trx && (trx as any).trxUpdateCacheTaskList ? await (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) + (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) return result } async upsertById(id: string, data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList([id], data, trx) const result = await super.upsertById(id, data, trx); - trx && (trx as any).trxUpdateCacheTaskList ? await (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) + (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) return result } async deleteByIds(ids: string[], trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList(ids, undefined, trx) const result = await super.deleteByIds(ids, trx); - trx && (trx as any).trxUpdateCacheTaskList ? await (trx as any).trxUpdateCacheTaskList(this, ids, dataList) : await this.deleteCache(ids, dataList) + (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, ids, dataList) : await this.deleteCache(ids, dataList) return result } From d46c8ed76e2815e564db2908e33a0fe91f780694 Mon Sep 17 00:00:00 2001 From: ityifan <329686198@qq.com> Date: Fri, 19 Sep 2025 17:11:24 +0800 Subject: [PATCH 09/26] =?UTF-8?q?=E6=96=B0=E5=A2=9Eif=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/MysqlCache.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/services/MysqlCache.ts b/src/services/MysqlCache.ts index a4a7c59..89291a3 100644 --- a/src/services/MysqlCache.ts +++ b/src/services/MysqlCache.ts @@ -28,35 +28,35 @@ export class MysqlCache extends MysqlNative { async updateById(id: string, data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList([id], data, trx) const result = await super.updateById(id, data, trx); - (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) + if (result) { (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) } return result } async updateByIds(ids: string[], data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList(ids, data, trx) const result = await super.updateByIds(ids, data, trx); - (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, ids, dataList) : await this.deleteCache(ids, dataList) + if (result) { (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, ids, dataList) : await this.deleteCache(ids, dataList) } return result } async updateForQueryById(id: string, query: CoaMysql.Query, data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList([id], data, trx) const result = await super.updateForQueryById(id, query, data, trx); - (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) + if (result) { (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) } return result } async upsertById(id: string, data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList([id], data, trx) const result = await super.upsertById(id, data, trx); - (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) + if (result) { (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) } return result } async deleteByIds(ids: string[], trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList(ids, undefined, trx) const result = await super.deleteByIds(ids, trx); - (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, ids, dataList) : await this.deleteCache(ids, dataList) + if (result) { (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, ids, dataList) : await this.deleteCache(ids, dataList) } return result } From 8cc6e5090f0cbae2aaa9434a09342f9ac5d0788d Mon Sep 17 00:00:00 2001 From: ityifan <329686198@qq.com> Date: Fri, 19 Sep 2025 17:34:11 +0800 Subject: [PATCH 10/26] =?UTF-8?q?=E5=A2=9E=E5=8A=A0if?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/MysqlCache.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/MysqlCache.ts b/src/services/MysqlCache.ts index 89291a3..b8f0c6a 100644 --- a/src/services/MysqlCache.ts +++ b/src/services/MysqlCache.ts @@ -49,7 +49,7 @@ export class MysqlCache extends MysqlNative { async upsertById(id: string, data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList([id], data, trx) const result = await super.upsertById(id, data, trx); - if (result) { (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) } + (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) return result } From 73b5f4fda07c0dd75ad85c1dba125221b6740081 Mon Sep 17 00:00:00 2001 From: ityifan <329686198@qq.com> Date: Fri, 19 Sep 2025 18:01:02 +0800 Subject: [PATCH 11/26] =?UTF-8?q?=E7=A7=BB=E9=99=A4trx.id?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libs/MysqlBin.ts | 3 --- src/test/demo.ts | 3 ++- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libs/MysqlBin.ts b/src/libs/MysqlBin.ts index f56852a..fc3dc30 100644 --- a/src/libs/MysqlBin.ts +++ b/src/libs/MysqlBin.ts @@ -1,6 +1,5 @@ import { echo } from 'coa-echo' import { CoaError } from 'coa-error' -import { secure } from 'coa-secure' import { MysqlCache } from '../services/MysqlCache' import { CoaMysql } from '../typings' import { Knex } from './Knex' @@ -33,11 +32,9 @@ export class MysqlBin { } async safeTransaction(handler: (trx: CoaMysql.Transaction) => Promise): Promise { - let cacheTasks = [] as Array<{ model: MysqlCache, ids: string[], dataList: any[] }> const result = await this.io.transaction(async (trx: any) => { - trx.id ||= secure.id25(`${Date.now()}-${Math.floor(Math.random() * 1e6).toString().padStart(6, '0')}`) // 收集事务更新缓存数据 trx.trxUpdateCacheTaskList = async (model: MysqlCache, ids: string[], dataList: any[]) => { cacheTasks.push({ model, ids, dataList }) diff --git a/src/test/demo.ts b/src/test/demo.ts index 3f7d6c9..1be6614 100644 --- a/src/test/demo.ts +++ b/src/test/demo.ts @@ -69,7 +69,8 @@ const User = new (class extends MysqlCache { title: '用户表', // 表的备注名称 scheme: userScheme, // 表的默认结构 pick: ['userId', 'name'], // 查询列表时显示的字段信息 - caches: { index: ['name'], count: ['userId', 'name'] } + caches: { index: ['name'], count: ['userId', 'name'] }, + }, mysqlBin, redisCache, From 2f471399e98ad8e59b938aad4499cc03d8bb8dcd Mon Sep 17 00:00:00 2001 From: ityifan <329686198@qq.com> Date: Fri, 19 Sep 2025 19:01:36 +0800 Subject: [PATCH 12/26] =?UTF-8?q?=E5=9B=9E=E9=80=80demo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/demo.ts | 182 ++++++++++++++++++++++++++--------------------- 1 file changed, 102 insertions(+), 80 deletions(-) diff --git a/src/test/demo.ts b/src/test/demo.ts index 1be6614..2752880 100644 --- a/src/test/demo.ts +++ b/src/test/demo.ts @@ -1,67 +1,68 @@ /* eslint-disable @typescript-eslint/no-redeclare */ // @ts-nocheck -import { $, _ } from 'coa-helper' -import { RedisBin, RedisCache } from 'coa-redis' -import { MysqlBin, MysqlCache } from '..' +import { CoaMysql, MysqlBin, MysqlNative } from '..' + // MySQL配置 const mysqlConfig = { host: '127.0.0.1', port: 3306, user: 'root', - password: '19990728', + password: 'root', charset: 'utf8mb4', trace: true, debug: false, databases: { - main: { database: 'mm-site-t1', ms: 7 * 24 * 3600 * 1000 }, + main: { database: 'test', ms: 7 * 24 * 3600 * 1000 }, + other: { database: 'other', ms: 7 * 24 * 3600 * 1000 }, }, } -const redisConfig = { - host: '127.0.0.1', - port: 6379, - password: '', - db: 1, - prefix: '', - trace: false, - -} -const redisBin = new RedisBin(redisConfig) -const redisCache = new RedisCache(redisBin) - // 初始化Mysql基本连接,后续所有模型均依赖此实例 const mysqlBin = new MysqlBin(mysqlConfig) +// 基本SQL操作 + +// 插入数据 https://knexjs.org/#Builder-insert +await mysqlBin.io.table('user').insert({ userId: 'user-a', name: 'A', mobile: '15010001001', gender: 1, language: 'zh-CN', status: 1 }) + +// 查询全部数据,详见 https://knexjs.org/#Builder-select +await mysqlBin.io.table('user').select() +await mysqlBin.io.select('*').from('user') + +// 带条件查询,详见 https://knexjs.org/#Builder-where +await mysqlBin.io.table('user').where('status', '=', 1) + +// 修改数据,详见 http://knexjs.org/#Builder-update +await mysqlBin.io.table('user').update({ name: 'AA', gender: 2 }).where({ userId: 'user-a' }) + +// 删除数据,详见 http://knexjs.org/#Builder-del%20/%20delete +await mysqlBin.io.table('user').delete().where({ userId: 'user-a' }) + +// 通过mysqlBin定义一个模型的基类,各个模型都可以使用这个基类 +export class MysqlNativeModel extends MysqlNative { + constructor(option: CoaMysql.ModelOption) { + // 将实例配置bin绑定 + super(option, mysqlBin) + } + + // 也可以定义一些通用方法 + commonMethod() { + // do something + } +} + +// 定义User默认结构 const userScheme = { userId: '' as string, name: '' as string, - mobile: '' as string, - avatar: '' as string, - gender: 1 as number, - language: '' as string, - status: 1 as number, created: 0 as number, updated: 0 as number, } - -// const userScheme1 = { -// userId: '' as string, -// name: '' as string, -// mobile: '' as string, -// avatar: '' as string, -// gender: 1 as number, -// language: '' as string, -// status: 1 as number, -// created: 0 as number, -// updated: 0 as number, -// } - // 定义User类型(通过默认结构自动生成) type UserScheme = typeof userScheme - // 通过基类初始化 -const User = new (class extends MysqlCache { +const User = new (class extends MysqlNative { constructor() { super( { @@ -69,52 +70,73 @@ const User = new (class extends MysqlCache { title: '用户表', // 表的备注名称 scheme: userScheme, // 表的默认结构 pick: ['userId', 'name'], // 查询列表时显示的字段信息 - caches: { index: ['name'], count: ['userId', 'name'] }, - }, - mysqlBin, - redisCache, - ) + mysqlBin + ) // 绑定配置实例bin + } + + // 自定义方法 + async customMethod() { + // 做一些事情 } })() -// const User1 = new (class extends MysqlCache { -// constructor() { -// super( -// { -// name: 'User1', // 表名,默认会转化为下划线(snackCase)形式,如 User->user UserPhoto->user_photo -// title: '用户表', // 表的备注名称 -// scheme: userScheme1, // 表的默认结构 -// pick: ['userId', 'name'], // 查询列表时显示的字段信息 -// }, -// mysqlBin, -// redisCache, -// ) -// } -// })() +// 通过基类模型定义用户模型 +const User = new (class extends MysqlNativeModel { + constructor() { + super({ name: 'User', title: '用户表', scheme: userScheme, pick: ['userId', 'name'] }) + } + + // 自定义方法 + async customMethodForUser() { + // 做一些事情 + } +})() + +// 通过基类模型定义管理员模型 +const Manager = new (class extends MysqlNativeModel { + constructor() { + super({ name: 'Manager', title: '管理员表', scheme: userScheme, pick: ['userId', 'name'] }) + } +})() + +// 用户模型和管理员模型均可以调用公共方法 +await User.commonMethod() +await Manager.commonMethod() + +// 仅仅用户模型可以调用自定义方法 +await User.customMethodForUser() + +// 插入 +await User.insert({ name: '王小明', gender: 1 }) // 返回 'id001',即该条数据的 userId = 'id001' // 批量插入 -// await User.mInsert([ -// { name: '王小明', gender: 1 }, -// { name: '宋小华', gender: 1 }, -// ]) - -// await User.updateById('id002', { name: '李四' }) // 返回 1 -const a = async () => { - await User.checkById('41102319990728253X') - await mysqlBin.safeTransaction(async (trx: CoaMysql.Transaction) => { - await User.updateById('41102319990728253X', { name: 'mmm' }, trx) - for (let index = 0; index < 10; index++) { - const userId = `${_.now()}-${index}-Y` - await $.timeout(3000) - await User.insert({ userId, name: 'heyifan2' }, trx) - } - }) - const b = await User.checkById('41102319990728253X') - console.log(b); - // const id = await redisCache.clearUseless('*id') - // console.log('cRedis: ID类型过期缓存清除成功', id) - // const data = await redisCache.clearUseless('*data') - // console.log('cRedis: DATA类型过期缓存清除成功', data) -} -a() +await User.mInsert([ + { name: '王小明', gender: 1 }, + { name: '宋小华', gender: 1 }, +]) // 返回 ['id002','id003'] + +// 通过ID更新 +await User.updateById('id002', { name: '李四' }) // 返回 1 + +// 通过ID批量更新 +await User.updateByIds(['id002', 'id003'], { status: 2 }) // 返回 2 + +// 通过ID更新或插入(如果id存在就更新,如果不存在就插入) +await User.upsertById('id002', { name: '王小明', gender: 1 }) // 返回 1 ,更新了一条 userId = 'id02' 的数据 +await User.upsertById('id004', { name: '李四', gender: 1 }) // 返回 0 ,插入一条新数据,数据的 userId = 'id04' + +// 通过ID删除多个 +await User.deleteByIds(['id003', 'id004']) // 返回 2 + +// 通过ID查询一个,第二个参数设置返回结果所包含的数据 +await User.getById('id001', ['name']) // 数据为{userId:'id001',name:'王小明',gender:1,status:1,...} 实际返回 {userId:'id001',name:'王小明'} + +// 通过ID获取多个 +await User.mGetByIds(['id001', 'id002'], ['name']) // 返回 {id001:{userId:'id001',name:'王小明'},id002:{userId:'id002',name:'李四'}} + +// 截断表 +await User.truncate() // 无返回值,主要不报错即成功截断整个表 + +// 自定义方法 +await User.customMethod() // 执行自定义方法 \ No newline at end of file From d98bb4de7f75493ec8e09e3e781f6d812c5586e6 Mon Sep 17 00:00:00 2001 From: ityifan <329686198@qq.com> Date: Mon, 22 Sep 2025 10:45:43 +0800 Subject: [PATCH 13/26] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AE=89=E5=85=A8?= =?UTF-8?q?=E4=BA=8B=E5=8A=A1=E7=9A=84=E6=96=B9=E6=B3=95=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/MysqlSafeTransaction.ts | 28 ++++++++++++++++++++++++++ src/index.ts | 10 +++++---- src/libs/MysqlBin.ts | 22 -------------------- src/services/MysqlCache.ts | 27 +++++++++++++++---------- 4 files changed, 50 insertions(+), 37 deletions(-) create mode 100644 src/components/MysqlSafeTransaction.ts diff --git a/src/components/MysqlSafeTransaction.ts b/src/components/MysqlSafeTransaction.ts new file mode 100644 index 0000000..bcc30b8 --- /dev/null +++ b/src/components/MysqlSafeTransaction.ts @@ -0,0 +1,28 @@ +import { RedisCache } from "coa-redis" +import { MysqlBin } from "../libs/MysqlBin" +import { CoaMysql } from "../typings" + +export class MysqlSafeTransaction { + private readonly bin: MysqlBin + private readonly cache: RedisCache + + constructor(bin: MysqlBin, cache: RedisCache) { + this.bin = bin + this.cache = cache + } + + async safeTransaction(handler: (trx: CoaMysql.Transaction) => Promise): Promise { + let clearCacheNsps: any[] = [] + const result = await this.bin.io.transaction(async (trx: any) => { + const result = await handler(trx) + clearCacheNsps = trx.clearCacheNsps || [] + return result + }) + + // 统一清理事务更新缓存 + if (this.cache && clearCacheNsps.length > 0) { + await this.cache.mDelete(clearCacheNsps) + } + return result + } +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 4aeee94..351f65e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,8 @@ -export { CoaMysql } from './typings' +export { MysqlSafeTransaction } from './components/MysqlSafeTransaction' +export { MysqlStorage } from './components/MysqlStorage' +export { MysqlUuid } from './components/MysqlUuid' export { MysqlBin } from './libs/MysqlBin' -export { MysqlNative } from './services/MysqlNative' export { MysqlCache } from './services/MysqlCache' -export { MysqlUuid } from './components/MysqlUuid' -export { MysqlStorage } from './components/MysqlStorage' +export { MysqlNative } from './services/MysqlNative' +export { CoaMysql } from './typings' + diff --git a/src/libs/MysqlBin.ts b/src/libs/MysqlBin.ts index fc3dc30..141b79d 100644 --- a/src/libs/MysqlBin.ts +++ b/src/libs/MysqlBin.ts @@ -1,6 +1,5 @@ import { echo } from 'coa-echo' import { CoaError } from 'coa-error' -import { MysqlCache } from '../services/MysqlCache' import { CoaMysql } from '../typings' import { Knex } from './Knex' export class MysqlBin { @@ -30,25 +29,4 @@ export class MysqlBin { this.config = config this.io = io } - - async safeTransaction(handler: (trx: CoaMysql.Transaction) => Promise): Promise { - let cacheTasks = [] as Array<{ model: MysqlCache, ids: string[], dataList: any[] }> - - const result = await this.io.transaction(async (trx: any) => { - // 收集事务更新缓存数据 - trx.trxUpdateCacheTaskList = async (model: MysqlCache, ids: string[], dataList: any[]) => { - cacheTasks.push({ model, ids, dataList }) - } - return await handler(trx) - }) - // 统一清理事务更新缓存 - for (const task of cacheTasks) { - await task.model.deleteCache(task.ids, task.dataList) - } - - // 初始数组 减少trx未及时销毁时的内存占用 - cacheTasks = [] - - return result - } } diff --git a/src/services/MysqlCache.ts b/src/services/MysqlCache.ts index b8f0c6a..ea60ea5 100644 --- a/src/services/MysqlCache.ts +++ b/src/services/MysqlCache.ts @@ -15,48 +15,48 @@ export class MysqlCache extends MysqlNative { async insert(data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const id = await super.insert(data, trx); - (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, [id], [data]) : await this.deleteCache([id], [data]) + await this.deleteCache([id], [data], trx) return id } async mInsert(dataList: Array>, trx?: CoaMysql.Transaction) { const ids = await super.mInsert(dataList, trx); - (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, ids, dataList) : await this.deleteCache(ids, dataList) + await this.deleteCache(ids, dataList, trx) return ids } async updateById(id: string, data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList([id], data, trx) - const result = await super.updateById(id, data, trx); - if (result) { (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) } + const result = await super.updateById(id, data, trx) + await this.deleteCache([id], dataList, trx) return result } async updateByIds(ids: string[], data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList(ids, data, trx) const result = await super.updateByIds(ids, data, trx); - if (result) { (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, ids, dataList) : await this.deleteCache(ids, dataList) } + await this.deleteCache(ids, dataList, trx) return result } async updateForQueryById(id: string, query: CoaMysql.Query, data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList([id], data, trx) const result = await super.updateForQueryById(id, query, data, trx); - if (result) { (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) } + await this.deleteCache([id], dataList, trx) return result } async upsertById(id: string, data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList([id], data, trx) const result = await super.upsertById(id, data, trx); - (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, [id], dataList) : await this.deleteCache([id], dataList) + await this.deleteCache([id], dataList, trx) return result } async deleteByIds(ids: string[], trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList(ids, undefined, trx) const result = await super.deleteByIds(ids, trx); - if (result) { (trx && (trx as any).trxUpdateCacheTaskList) ? await (trx as any).trxUpdateCacheTaskList(this, ids, dataList) : await this.deleteCache(ids, dataList) } + await this.deleteCache(ids, dataList, trx) return result } @@ -152,7 +152,12 @@ export class MysqlCache extends MysqlNative { return resultList } - async deleteCache(ids: string[], dataList: Array>) { + async deleteCache(ids: string[], dataList: Array>, trx?: CoaMysql.Transaction) { + if (trx && !(trx as any).clearCacheNsps) { + (trx as any).clearCacheNsps = [] as any + (trx as any).clearCacheNsps.push([this.getCacheNsp('id'), ids]); + (trx as any).clearCacheNsps.push([this.getCacheNsp('data'), []]) + } const deleteIds = [] as CoaRedis.CacheDelete[] deleteIds.push([this.getCacheNsp('id'), ids]) deleteIds.push([this.getCacheNsp('data'), []]) @@ -166,9 +171,9 @@ export class MysqlCache extends MysqlNative { data?.[key] && ids.push(data[key]) }) ids.push(...keys.slice(1)) - ids.length && deleteIds.push([this.getCacheNsp(name, key), ids]) + trx ? (ids.length && (trx as any).clearCacheNsps.push([this.getCacheNsp(name, key), ids])) : (ids.length && deleteIds.push([this.getCacheNsp(name, key), ids])) }) }) - await this.redisCache.mDelete(deleteIds) + if (!trx) await this.redisCache.mDelete(deleteIds) } } From 4020990720d918f09c350fd9f05e6f69cb8e0837 Mon Sep 17 00:00:00 2001 From: ityifan <329686198@qq.com> Date: Mon, 22 Sep 2025 10:50:05 +0800 Subject: [PATCH 14/26] =?UTF-8?q?=E6=81=A2=E5=A4=8Ddemo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/demo.ts | 5 ++ src/test/demoSafeTransaction.ts | 118 ++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 src/test/demoSafeTransaction.ts diff --git a/src/test/demo.ts b/src/test/demo.ts index 2752880..010b7f1 100644 --- a/src/test/demo.ts +++ b/src/test/demo.ts @@ -55,6 +55,11 @@ export class MysqlNativeModel extends MysqlNative { const userScheme = { userId: '' as string, name: '' as string, + mobile: '' as string, + avatar: '' as string, + gender: 1 as number, + language: '' as string, + status: 1 as number, created: 0 as number, updated: 0 as number, } diff --git a/src/test/demoSafeTransaction.ts b/src/test/demoSafeTransaction.ts new file mode 100644 index 0000000..fb0014f --- /dev/null +++ b/src/test/demoSafeTransaction.ts @@ -0,0 +1,118 @@ +/* eslint-disable @typescript-eslint/no-redeclare */ +// @ts-nocheck +import { $, _ } from 'coa-helper' +import { RedisBin, RedisCache } from 'coa-redis' +import { MysqlBin, MysqlCache, MysqlSafeTransaction } from '..' +// MySQL配置 +const mysqlConfig = { + host: '127.0.0.1', + port: 3306, + user: 'root', + password: '', + charset: 'utf8mb4', + trace: true, + debug: false, + databases: { + main: { database: 'coa-mysql', ms: 7 * 24 * 3600 * 1000 }, + }, +} + +const redisConfig = { + host: '127.0.0.1', + port: 6379, + password: '', + db: 1, + prefix: 'coa-mysql', + trace: false, + +} +const redisBin = new RedisBin(redisConfig) +const redisCache = new RedisCache(redisBin) + +// 初始化Mysql基本连接,后续所有模型均依赖此实例 +const mysqlBin = new MysqlBin(mysqlConfig) +const safeTransaction = new MysqlSafeTransaction(mysqlBin) + +const userScheme = { + userId: '' as string, + name: '' as string, + mobile: '' as string, + avatar: '' as string, + gender: 1 as number, + language: '' as string, + status: 1 as number, + created: 0 as number, + updated: 0 as number, +} + +// const userScheme1 = { +// userId: '' as string, +// name: '' as string, +// mobile: '' as string, +// avatar: '' as string, +// gender: 1 as number, +// language: '' as string, +// status: 1 as number, +// created: 0 as number, +// updated: 0 as number, +// } + +// 定义User类型(通过默认结构自动生成) +type UserScheme = typeof userScheme + + +// 通过基类初始化 +const User = new (class extends MysqlCache { + constructor() { + super( + { + name: 'User', // 表名,默认会转化为下划线(snackCase)形式,如 User->user UserPhoto->user_photo + title: '用户表', // 表的备注名称 + scheme: userScheme, // 表的默认结构 + pick: ['userId', 'name'], // 查询列表时显示的字段信息 + caches: { index: ['name'], count: ['userId', 'name'] }, + + }, + mysqlBin, + redisCache, + ) + } +})() + +// const User1 = new (class extends MysqlCache { +// constructor() { +// super( +// { +// name: 'User1', // 表名,默认会转化为下划线(snackCase)形式,如 User->user UserPhoto->user_photo +// title: '用户表', // 表的备注名称 +// scheme: userScheme1, // 表的默认结构 +// pick: ['userId', 'name'], // 查询列表时显示的字段信息 +// }, +// mysqlBin, +// redisCache, +// ) +// } +// })() + +// 批量插入 +// await User.mInsert([ +// { name: '王小明', gender: 1 }, +// { name: '宋小华', gender: 1 }, +// ]) + +// await User.updateById('id002', { name: '李四' }) // 返回 1 +const a = async () => { + await User.checkById('41102319990728253X') + await $.timeout(3000) + await safeTransaction.safeTransaction(async (trx: CoaMysql.Transaction) => { + await User.updateById('41102319990728253X', { name: 'mmm' }) + for (let index = 0; index < 10; index++) { + const userId = `${_.now()}-${index}-Y` + await User.insert({ userId, name: 'heyifan2' }, trx) + } + }) + await $.timeout(3000) + const b = await User.checkById('41102319990728253X') + console.log(b); +} +a() From be54b482e46efe60a13e7db87d60f2dfe2c67eec Mon Sep 17 00:00:00 2001 From: ityifan <329686198@qq.com> Date: Mon, 22 Sep 2025 10:53:40 +0800 Subject: [PATCH 15/26] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/demoSafeTransaction.ts | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/src/test/demoSafeTransaction.ts b/src/test/demoSafeTransaction.ts index fb0014f..33039bf 100644 --- a/src/test/demoSafeTransaction.ts +++ b/src/test/demoSafeTransaction.ts @@ -45,17 +45,6 @@ const userScheme = { updated: 0 as number, } -// const userScheme1 = { -// userId: '' as string, -// name: '' as string, -// mobile: '' as string, -// avatar: '' as string, -// gender: 1 as number, -// language: '' as string, -// status: 1 as number, -// created: 0 as number, -// updated: 0 as number, -// } // 定义User类型(通过默认结构自动生成) type UserScheme = typeof userScheme @@ -79,28 +68,6 @@ const User = new (class extends MysqlCache { } })() -// const User1 = new (class extends MysqlCache { -// constructor() { -// super( -// { -// name: 'User1', // 表名,默认会转化为下划线(snackCase)形式,如 User->user UserPhoto->user_photo -// title: '用户表', // 表的备注名称 -// scheme: userScheme1, // 表的默认结构 -// pick: ['userId', 'name'], // 查询列表时显示的字段信息 -// }, -// mysqlBin, -// redisCache, -// ) -// } -// })() - -// 批量插入 -// await User.mInsert([ -// { name: '王小明', gender: 1 }, -// { name: '宋小华', gender: 1 }, -// ]) - -// await User.updateById('id002', { name: '李四' }) // 返回 1 const a = async () => { await User.checkById('41102319990728253X') await $.timeout(3000) From a44846e959bdfff42da28eba8b97106353affa30 Mon Sep 17 00:00:00 2001 From: ityifan <329686198@qq.com> Date: Mon, 22 Sep 2025 18:18:40 +0800 Subject: [PATCH 16/26] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/MysqlCache.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/services/MysqlCache.ts b/src/services/MysqlCache.ts index ea60ea5..d501eb2 100644 --- a/src/services/MysqlCache.ts +++ b/src/services/MysqlCache.ts @@ -155,6 +155,8 @@ export class MysqlCache extends MysqlNative { async deleteCache(ids: string[], dataList: Array>, trx?: CoaMysql.Transaction) { if (trx && !(trx as any).clearCacheNsps) { (trx as any).clearCacheNsps = [] as any + } + if (trx && (trx as any).clearCacheNsps) { (trx as any).clearCacheNsps.push([this.getCacheNsp('id'), ids]); (trx as any).clearCacheNsps.push([this.getCacheNsp('data'), []]) } From 6200b739a731eec98dc28713663b69a0d6fe5814 Mon Sep 17 00:00:00 2001 From: ityifan <329686198@qq.com> Date: Mon, 22 Sep 2025 18:25:09 +0800 Subject: [PATCH 17/26] =?UTF-8?q?=E5=AE=9A=E4=B9=89=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/MysqlCache.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/MysqlCache.ts b/src/services/MysqlCache.ts index d501eb2..3b44f33 100644 --- a/src/services/MysqlCache.ts +++ b/src/services/MysqlCache.ts @@ -154,7 +154,7 @@ export class MysqlCache extends MysqlNative { async deleteCache(ids: string[], dataList: Array>, trx?: CoaMysql.Transaction) { if (trx && !(trx as any).clearCacheNsps) { - (trx as any).clearCacheNsps = [] as any + (trx as any).clearCacheNsps = [] as CoaRedis.CacheDelete[] } if (trx && (trx as any).clearCacheNsps) { (trx as any).clearCacheNsps.push([this.getCacheNsp('id'), ids]); From 7259845cfdbaf2163843364eee3b7767dca5ded7 Mon Sep 17 00:00:00 2001 From: ityifan <329686198@qq.com> Date: Mon, 22 Sep 2025 18:39:47 +0800 Subject: [PATCH 18/26] =?UTF-8?q?=E4=BF=AE=E6=94=B9demo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/demoSafeTransaction.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/demoSafeTransaction.ts b/src/test/demoSafeTransaction.ts index 33039bf..264efce 100644 --- a/src/test/demoSafeTransaction.ts +++ b/src/test/demoSafeTransaction.ts @@ -69,17 +69,17 @@ const User = new (class extends MysqlCache { })() const a = async () => { - await User.checkById('41102319990728253X') + await User.checkById('411******728253X') await $.timeout(3000) await safeTransaction.safeTransaction(async (trx: CoaMysql.Transaction) => { - await User.updateById('41102319990728253X', { name: 'mmm' }) + await User.updateById('411******728253X', { name: 'mmm' }) for (let index = 0; index < 10; index++) { const userId = `${_.now()}-${index}-Y` await User.insert({ userId, name: 'heyifan2' }, trx) } }) await $.timeout(3000) - const b = await User.checkById('41102319990728253X') + const b = await User.checkById('411******728253X') console.log(b); } a() From 58952fc41c4340ac8340b26b8ad4cb5be73f018e Mon Sep 17 00:00:00 2001 From: ityifan <329686198@qq.com> Date: Wed, 24 Sep 2025 16:30:10 +0800 Subject: [PATCH 19/26] =?UTF-8?q?=E6=96=B0=E5=A2=9Eif=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/MysqlCache.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/services/MysqlCache.ts b/src/services/MysqlCache.ts index 3b44f33..8375cd5 100644 --- a/src/services/MysqlCache.ts +++ b/src/services/MysqlCache.ts @@ -28,21 +28,21 @@ export class MysqlCache extends MysqlNative { async updateById(id: string, data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList([id], data, trx) const result = await super.updateById(id, data, trx) - await this.deleteCache([id], dataList, trx) + if (result) await this.deleteCache([id], dataList, trx) return result } async updateByIds(ids: string[], data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList(ids, data, trx) const result = await super.updateByIds(ids, data, trx); - await this.deleteCache(ids, dataList, trx) + if (result) await this.deleteCache(ids, dataList, trx) return result } async updateForQueryById(id: string, query: CoaMysql.Query, data: CoaMysql.SafePartial, trx?: CoaMysql.Transaction) { const dataList = await this.getCacheChangedDataList([id], data, trx) const result = await super.updateForQueryById(id, query, data, trx); - await this.deleteCache([id], dataList, trx) + if (result) await this.deleteCache([id], dataList, trx) return result } From c5cf3ba8308826c29d948bb5586e0f74faa15346 Mon Sep 17 00:00:00 2001 From: ityifan <329686198@qq.com> Date: Thu, 25 Sep 2025 09:18:18 +0800 Subject: [PATCH 20/26] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=A4=9A=E4=BD=99?= =?UTF-8?q?=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/MysqlSafeTransaction.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/components/MysqlSafeTransaction.ts b/src/components/MysqlSafeTransaction.ts index bcc30b8..b1db4e7 100644 --- a/src/components/MysqlSafeTransaction.ts +++ b/src/components/MysqlSafeTransaction.ts @@ -19,10 +19,7 @@ export class MysqlSafeTransaction { return result }) - // 统一清理事务更新缓存 - if (this.cache && clearCacheNsps.length > 0) { - await this.cache.mDelete(clearCacheNsps) - } + if (clearCacheNsps.length > 0) { await this.cache.mDelete(clearCacheNsps) } return result } } \ No newline at end of file From f869ab19152ff6479e7babe5a54dfa68dd20dbb3 Mon Sep 17 00:00:00 2001 From: ityifan <329686198@qq.com> Date: Sun, 28 Sep 2025 13:50:35 +0800 Subject: [PATCH 21/26] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/MysqlSafeTransaction.ts | 4 ++++ src/services/MysqlCache.ts | 31 +++++++++++++------------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/components/MysqlSafeTransaction.ts b/src/components/MysqlSafeTransaction.ts index b1db4e7..5c42d9b 100644 --- a/src/components/MysqlSafeTransaction.ts +++ b/src/components/MysqlSafeTransaction.ts @@ -14,7 +14,11 @@ export class MysqlSafeTransaction { async safeTransaction(handler: (trx: CoaMysql.Transaction) => Promise): Promise { let clearCacheNsps: any[] = [] const result = await this.bin.io.transaction(async (trx: any) => { + trx.__isSafeTransaction = true + trx.clearCacheNsps = [] + const result = await handler(trx) + clearCacheNsps = trx.clearCacheNsps || [] return result }) diff --git a/src/services/MysqlCache.ts b/src/services/MysqlCache.ts index 8375cd5..4f671a0 100644 --- a/src/services/MysqlCache.ts +++ b/src/services/MysqlCache.ts @@ -70,11 +70,11 @@ export class MysqlCache extends MysqlNative { } async getIdBy(field: string, value: string | number, trx?: CoaMysql.Transaction) { - return trx ? await super.getIdBy(field, value, trx) : await this.redisCache.warp(this.getCacheNsp('index', field), '' + value, async () => await super.getIdBy(field, value, trx)) + return (trx as any).__isSafeTransaction ? await super.getIdBy(field, value, trx) : await this.redisCache.warp(this.getCacheNsp('index', field), '' + value, async () => await super.getIdBy(field, value, trx)) } async mGetByIds(ids: string[], pick = this.pick, trx?: CoaMysql.Transaction, ms = this.ms, force = false) { - const result = trx ? await super.mGetByIds(ids, this.columns, trx) : await this.redisCache.mWarp(this.getCacheNsp('id'), ids, async ids => await super.mGetByIds(ids, this.columns, trx), ms, force) + const result = (trx as any).__isSafeTransaction ? await super.mGetByIds(ids, this.columns, trx) : await this.redisCache.mWarp(this.getCacheNsp('id'), ids, async ids => await super.mGetByIds(ids, this.columns, trx), ms, force) _.forEach(result, (v, k) => { result[k] = this.pickResult(v, pick) }) @@ -88,23 +88,23 @@ export class MysqlCache extends MysqlNative { protected async findListCount(finger: Array>, query: CoaMysql.Query, trx?: CoaMysql.Transaction) { const cacheId = 'list-count:' + secure.sha1($.sortQueryString(...finger)) - return trx ? await super.selectListCount(query, trx) : await this.redisCache.warp(this.getCacheNsp('data'), cacheId, async () => await super.selectListCount(query, trx)) + return (trx as any)?.__isSafeTransaction ? await super.selectListCount(query, trx) : await this.redisCache.warp(this.getCacheNsp('data'), cacheId, async () => await super.selectListCount(query, trx)) } protected async findIdList(finger: Array>, query: CoaMysql.Query, trx?: CoaMysql.Transaction) { const cacheId = 'list:' + secure.sha1($.sortQueryString(...finger)) - return trx ? await super.selectIdList(query, trx) : await this.redisCache.warp(this.getCacheNsp('data'), cacheId, async () => await super.selectIdList(query, trx)) + return (trx as any)?.__isSafeTransaction ? await super.selectIdList(query, trx) : await this.redisCache.warp(this.getCacheNsp('data'), cacheId, async () => await super.selectIdList(query, trx)) } protected async findIdSortList(finger: Array>, pager: CoaMysql.Pager, query: CoaMysql.Query, trx?: CoaMysql.Transaction) { const cacheId = `sort-list:${pager.rows}:${pager.last}:` + secure.sha1($.sortQueryString(...finger)) - return trx ? await super.selectIdSortList(pager, query, trx) : await this.redisCache.warp(this.getCacheNsp('data'), cacheId, async () => await super.selectIdSortList(pager, query, trx)) + return (trx as any)?.__isSafeTransaction ? await super.selectIdSortList(pager, query, trx) : await this.redisCache.warp(this.getCacheNsp('data'), cacheId, async () => await super.selectIdSortList(pager, query, trx)) } protected async findIdViewList(finger: Array>, pager: CoaMysql.Pager, query: CoaMysql.Query, trx?: CoaMysql.Transaction) { const cacheId = `view-list:${pager.rows}:${pager.page}:` + secure.sha1($.sortQueryString(...finger)) const count = await this.findListCount(finger, query, trx) - return trx ? await super.selectIdViewList(pager, query, trx, count) : await this.redisCache.warp(this.getCacheNsp('data'), cacheId, async () => await super.selectIdViewList(pager, query, trx, count)) + return (trx as any)?.__isSafeTransaction ? await super.selectIdViewList(pager, query, trx, count) : await this.redisCache.warp(this.getCacheNsp('data'), cacheId, async () => await super.selectIdViewList(pager, query, trx, count)) } protected async mGetCountBy(field: string, ids: string[], trx?: CoaMysql.Transaction) { @@ -114,7 +114,7 @@ export class MysqlCache extends MysqlNative { _.forEach(rows, ({ id, count }) => (result[id] = count)) return result } - const result = trx ? await queryFunction() : await this.redisCache.mWarp(this.getCacheNsp('count', field), ids, queryFunction) + const result = (trx as any)?.__isSafeTransaction ? await queryFunction() : await this.redisCache.mWarp(this.getCacheNsp('count', field), ids, queryFunction) return result } @@ -125,7 +125,7 @@ export class MysqlCache extends MysqlNative { const rows = await qb return (rows[0]?.count as number) || 0 } - const result = trx ? await queryFunction() : await this.redisCache.warp(this.getCacheNsp('count', field), value, queryFunction) + const result = (trx as any)?.__isSafeTransaction ? await queryFunction() : await this.redisCache.warp(this.getCacheNsp('count', field), value, queryFunction) return result } @@ -153,12 +153,9 @@ export class MysqlCache extends MysqlNative { } async deleteCache(ids: string[], dataList: Array>, trx?: CoaMysql.Transaction) { - if (trx && !(trx as any).clearCacheNsps) { - (trx as any).clearCacheNsps = [] as CoaRedis.CacheDelete[] - } - if (trx && (trx as any).clearCacheNsps) { - (trx as any).clearCacheNsps.push([this.getCacheNsp('id'), ids]); - (trx as any).clearCacheNsps.push([this.getCacheNsp('data'), []]) + if ((trx as any)?.__isSafeTransaction) { + (trx as any)?.clearCacheNsps.push([this.getCacheNsp('id'), ids]); + (trx as any)?.clearCacheNsps.push([this.getCacheNsp('data'), []]) } const deleteIds = [] as CoaRedis.CacheDelete[] deleteIds.push([this.getCacheNsp('id'), ids]) @@ -173,9 +170,11 @@ export class MysqlCache extends MysqlNative { data?.[key] && ids.push(data[key]) }) ids.push(...keys.slice(1)) - trx ? (ids.length && (trx as any).clearCacheNsps.push([this.getCacheNsp(name, key), ids])) : (ids.length && deleteIds.push([this.getCacheNsp(name, key), ids])) + if (ids.length) { + ((trx as any)?.__isSafeTransaction) ? (trx as any)?.clearCacheNsps.push([this.getCacheNsp(name, key), ids]) : deleteIds.push([this.getCacheNsp(name, key), ids]) + } }) }) - if (!trx) await this.redisCache.mDelete(deleteIds) + if ((!trx as any).__isSafeTransaction) await this.redisCache.mDelete(deleteIds) } } From 069a2ddb6f3f4460e8c163b1128a07de5c2a01fd Mon Sep 17 00:00:00 2001 From: ityifan <329686198@qq.com> Date: Sun, 28 Sep 2025 13:56:05 +0800 Subject: [PATCH 22/26] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/MysqlCache.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/MysqlCache.ts b/src/services/MysqlCache.ts index 4f671a0..ed1ccaa 100644 --- a/src/services/MysqlCache.ts +++ b/src/services/MysqlCache.ts @@ -175,6 +175,6 @@ export class MysqlCache extends MysqlNative { } }) }) - if ((!trx as any).__isSafeTransaction) await this.redisCache.mDelete(deleteIds) + if (!(trx as any)?.__isSafeTransaction) await this.redisCache.mDelete(deleteIds) } } From e2a00fcf0704989798d8271cdde5e57afe7bf460 Mon Sep 17 00:00:00 2001 From: ityifan <329686198@qq.com> Date: Sun, 28 Sep 2025 13:59:28 +0800 Subject: [PATCH 23/26] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=86=97=E4=BD=99push?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/MysqlCache.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/services/MysqlCache.ts b/src/services/MysqlCache.ts index ed1ccaa..b36534c 100644 --- a/src/services/MysqlCache.ts +++ b/src/services/MysqlCache.ts @@ -153,13 +153,14 @@ export class MysqlCache extends MysqlNative { } async deleteCache(ids: string[], dataList: Array>, trx?: CoaMysql.Transaction) { + const deleteIds = [] as CoaRedis.CacheDelete[] if ((trx as any)?.__isSafeTransaction) { (trx as any)?.clearCacheNsps.push([this.getCacheNsp('id'), ids]); (trx as any)?.clearCacheNsps.push([this.getCacheNsp('data'), []]) + } else { + deleteIds.push([this.getCacheNsp('id'), ids]) + deleteIds.push([this.getCacheNsp('data'), []]) } - const deleteIds = [] as CoaRedis.CacheDelete[] - deleteIds.push([this.getCacheNsp('id'), ids]) - deleteIds.push([this.getCacheNsp('data'), []]) _.forEach(this.caches, (items, name) => { // name可能为index,count,或自定义 items.forEach(item => { From 8b8d6df4ecd28a678e63333655bbe9b0035ff36f Mon Sep 17 00:00:00 2001 From: ityifan <329686198@qq.com> Date: Sun, 28 Sep 2025 14:25:32 +0800 Subject: [PATCH 24/26] =?UTF-8?q?demo=E6=96=87=E4=BB=B6=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E7=A4=BA=E4=BE=8B=E5=8C=96=E5=8F=82=E6=95=B0=E4=BC=A0=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/demoSafeTransaction.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/demoSafeTransaction.ts b/src/test/demoSafeTransaction.ts index 264efce..74aa9e1 100644 --- a/src/test/demoSafeTransaction.ts +++ b/src/test/demoSafeTransaction.ts @@ -31,7 +31,7 @@ const redisCache = new RedisCache(redisBin) // 初始化Mysql基本连接,后续所有模型均依赖此实例 const mysqlBin = new MysqlBin(mysqlConfig) -const safeTransaction = new MysqlSafeTransaction(mysqlBin) +const safeTransaction = new MysqlSafeTransaction(mysqlBin, redisCache) const userScheme = { userId: '' as string, From 44367ac96948ac541bf016a5289bd0e48eeb036e Mon Sep 17 00:00:00 2001 From: ityifan <329686198@qq.com> Date: Sun, 28 Sep 2025 14:35:55 +0800 Subject: [PATCH 25/26] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E5=A3=B0=E6=98=8E=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/MysqlSafeTransaction.ts | 2 +- src/services/MysqlCache.ts | 22 +++++++++++----------- src/typings.ts | 5 ++++- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/components/MysqlSafeTransaction.ts b/src/components/MysqlSafeTransaction.ts index 5c42d9b..aeae061 100644 --- a/src/components/MysqlSafeTransaction.ts +++ b/src/components/MysqlSafeTransaction.ts @@ -13,7 +13,7 @@ export class MysqlSafeTransaction { async safeTransaction(handler: (trx: CoaMysql.Transaction) => Promise): Promise { let clearCacheNsps: any[] = [] - const result = await this.bin.io.transaction(async (trx: any) => { + const result = await this.bin.io.transaction(async (trx: CoaMysql.Transaction) => { trx.__isSafeTransaction = true trx.clearCacheNsps = [] diff --git a/src/services/MysqlCache.ts b/src/services/MysqlCache.ts index b36534c..6bb307a 100644 --- a/src/services/MysqlCache.ts +++ b/src/services/MysqlCache.ts @@ -70,11 +70,11 @@ export class MysqlCache extends MysqlNative { } async getIdBy(field: string, value: string | number, trx?: CoaMysql.Transaction) { - return (trx as any).__isSafeTransaction ? await super.getIdBy(field, value, trx) : await this.redisCache.warp(this.getCacheNsp('index', field), '' + value, async () => await super.getIdBy(field, value, trx)) + return trx?.__isSafeTransaction ? await super.getIdBy(field, value, trx) : await this.redisCache.warp(this.getCacheNsp('index', field), '' + value, async () => await super.getIdBy(field, value, trx)) } async mGetByIds(ids: string[], pick = this.pick, trx?: CoaMysql.Transaction, ms = this.ms, force = false) { - const result = (trx as any).__isSafeTransaction ? await super.mGetByIds(ids, this.columns, trx) : await this.redisCache.mWarp(this.getCacheNsp('id'), ids, async ids => await super.mGetByIds(ids, this.columns, trx), ms, force) + const result = trx?.__isSafeTransaction ? await super.mGetByIds(ids, this.columns, trx) : await this.redisCache.mWarp(this.getCacheNsp('id'), ids, async ids => await super.mGetByIds(ids, this.columns, trx), ms, force) _.forEach(result, (v, k) => { result[k] = this.pickResult(v, pick) }) @@ -88,23 +88,23 @@ export class MysqlCache extends MysqlNative { protected async findListCount(finger: Array>, query: CoaMysql.Query, trx?: CoaMysql.Transaction) { const cacheId = 'list-count:' + secure.sha1($.sortQueryString(...finger)) - return (trx as any)?.__isSafeTransaction ? await super.selectListCount(query, trx) : await this.redisCache.warp(this.getCacheNsp('data'), cacheId, async () => await super.selectListCount(query, trx)) + return trx?.__isSafeTransaction ? await super.selectListCount(query, trx) : await this.redisCache.warp(this.getCacheNsp('data'), cacheId, async () => await super.selectListCount(query, trx)) } protected async findIdList(finger: Array>, query: CoaMysql.Query, trx?: CoaMysql.Transaction) { const cacheId = 'list:' + secure.sha1($.sortQueryString(...finger)) - return (trx as any)?.__isSafeTransaction ? await super.selectIdList(query, trx) : await this.redisCache.warp(this.getCacheNsp('data'), cacheId, async () => await super.selectIdList(query, trx)) + return trx?.__isSafeTransaction ? await super.selectIdList(query, trx) : await this.redisCache.warp(this.getCacheNsp('data'), cacheId, async () => await super.selectIdList(query, trx)) } protected async findIdSortList(finger: Array>, pager: CoaMysql.Pager, query: CoaMysql.Query, trx?: CoaMysql.Transaction) { const cacheId = `sort-list:${pager.rows}:${pager.last}:` + secure.sha1($.sortQueryString(...finger)) - return (trx as any)?.__isSafeTransaction ? await super.selectIdSortList(pager, query, trx) : await this.redisCache.warp(this.getCacheNsp('data'), cacheId, async () => await super.selectIdSortList(pager, query, trx)) + return trx?.__isSafeTransaction ? await super.selectIdSortList(pager, query, trx) : await this.redisCache.warp(this.getCacheNsp('data'), cacheId, async () => await super.selectIdSortList(pager, query, trx)) } protected async findIdViewList(finger: Array>, pager: CoaMysql.Pager, query: CoaMysql.Query, trx?: CoaMysql.Transaction) { const cacheId = `view-list:${pager.rows}:${pager.page}:` + secure.sha1($.sortQueryString(...finger)) const count = await this.findListCount(finger, query, trx) - return (trx as any)?.__isSafeTransaction ? await super.selectIdViewList(pager, query, trx, count) : await this.redisCache.warp(this.getCacheNsp('data'), cacheId, async () => await super.selectIdViewList(pager, query, trx, count)) + return trx?.__isSafeTransaction ? await super.selectIdViewList(pager, query, trx, count) : await this.redisCache.warp(this.getCacheNsp('data'), cacheId, async () => await super.selectIdViewList(pager, query, trx, count)) } protected async mGetCountBy(field: string, ids: string[], trx?: CoaMysql.Transaction) { @@ -114,7 +114,7 @@ export class MysqlCache extends MysqlNative { _.forEach(rows, ({ id, count }) => (result[id] = count)) return result } - const result = (trx as any)?.__isSafeTransaction ? await queryFunction() : await this.redisCache.mWarp(this.getCacheNsp('count', field), ids, queryFunction) + const result = trx?.__isSafeTransaction ? await queryFunction() : await this.redisCache.mWarp(this.getCacheNsp('count', field), ids, queryFunction) return result } @@ -125,7 +125,7 @@ export class MysqlCache extends MysqlNative { const rows = await qb return (rows[0]?.count as number) || 0 } - const result = (trx as any)?.__isSafeTransaction ? await queryFunction() : await this.redisCache.warp(this.getCacheNsp('count', field), value, queryFunction) + const result = trx?.__isSafeTransaction ? await queryFunction() : await this.redisCache.warp(this.getCacheNsp('count', field), value, queryFunction) return result } @@ -154,7 +154,7 @@ export class MysqlCache extends MysqlNative { async deleteCache(ids: string[], dataList: Array>, trx?: CoaMysql.Transaction) { const deleteIds = [] as CoaRedis.CacheDelete[] - if ((trx as any)?.__isSafeTransaction) { + if (trx?.__isSafeTransaction) { (trx as any)?.clearCacheNsps.push([this.getCacheNsp('id'), ids]); (trx as any)?.clearCacheNsps.push([this.getCacheNsp('data'), []]) } else { @@ -172,10 +172,10 @@ export class MysqlCache extends MysqlNative { }) ids.push(...keys.slice(1)) if (ids.length) { - ((trx as any)?.__isSafeTransaction) ? (trx as any)?.clearCacheNsps.push([this.getCacheNsp(name, key), ids]) : deleteIds.push([this.getCacheNsp(name, key), ids]) + (trx?.__isSafeTransaction) ? (trx as any)?.clearCacheNsps.push([this.getCacheNsp(name, key), ids]) : deleteIds.push([this.getCacheNsp(name, key), ids]) } }) }) - if (!(trx as any)?.__isSafeTransaction) await this.redisCache.mDelete(deleteIds) + if (!trx?.__isSafeTransaction) await this.redisCache.mDelete(deleteIds) } } diff --git a/src/typings.ts b/src/typings.ts index 9408788..a91254d 100644 --- a/src/typings.ts +++ b/src/typings.ts @@ -7,7 +7,10 @@ export namespace CoaMysql { export type SafePartial = T extends {} ? Partial : any export type Query = (qb: Knex.QueryBuilder) => void export type QueryBuilder = Knex.QueryBuilder - export type Transaction = Knex.Transaction + export interface Transaction extends Knex.Transaction { + __isSafeTransaction?: boolean + clearCacheNsps?: any[] + } export interface Pager { rows: number last: number From 4b6043b9ab2b4bbfb09ccd39f60b9d757fe64d65 Mon Sep 17 00:00:00 2001 From: ityifan <329686198@qq.com> Date: Sun, 28 Sep 2025 14:46:26 +0800 Subject: [PATCH 26/26] =?UTF-8?q?=E8=A1=A5=E5=85=85getById=E6=96=B9?= =?UTF-8?q?=E6=B3=95=5F=5FisSafeTransaction=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/MysqlCache.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/MysqlCache.ts b/src/services/MysqlCache.ts index 6bb307a..cf1f7f3 100644 --- a/src/services/MysqlCache.ts +++ b/src/services/MysqlCache.ts @@ -65,7 +65,7 @@ export class MysqlCache extends MysqlNative { } async getById(id: string, pick = this.columns, trx?: CoaMysql.Transaction, ms = this.ms, force = false) { - const result = trx ? await super.getById(id, this.columns, trx) : await this.redisCache.warp(this.getCacheNsp('id'), id, async () => await super.getById(id, this.columns, trx), ms, force) + const result = trx?.__isSafeTransaction ? await super.getById(id, this.columns, trx) : await this.redisCache.warp(this.getCacheNsp('id'), id, async () => await super.getById(id, this.columns, trx), ms, force) return this.pickResult(result, pick) }