Skip to content

Commit 0b4d241

Browse files
committed
🐛 修复并发setValue导致的数据错误 #249
1 parent a6efaa7 commit 0b4d241

File tree

2 files changed

+70
-60
lines changed

2 files changed

+70
-60
lines changed

src/app/repo/value.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import Dexie from "dexie";
12
import { DAO, db } from "./dao";
23

34
export interface Value {
@@ -13,8 +14,12 @@ export interface Value {
1314
export class ValueDAO extends DAO<Value> {
1415
public tableName = "value";
1516

16-
constructor() {
17+
constructor(table?: Dexie.Table<Value, number>) {
1718
super();
18-
this.table = db.table(this.tableName);
19+
if (table) {
20+
this.table = table;
21+
} else {
22+
this.table = db.table(this.tableName);
23+
}
1924
}
2025
}

src/app/service/value/manager.ts

Lines changed: 63 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { Value, ValueDAO } from "@App/app/repo/value";
1010
import { ValueUpdateData } from "@App/runtime/content/exec_script";
1111
import CacheKey from "@App/pkg/utils/cache_key";
1212
import { isEqual } from "lodash";
13+
import { db } from "@App/app/repo/dao";
1314
import Cache from "../../cache";
1415
import Manager from "../manager";
1516
import ScriptManager from "../script/manager";
@@ -112,68 +113,72 @@ export class ValueManager extends Manager {
112113
// 更新数据库中的value
113114
let model: Value | undefined;
114115
let oldValue: any;
115-
if (script.metadata.storagename) {
116-
model = await this.valueDAO.findOne({
117-
storageName: script.metadata.storagename[0],
118-
key,
119-
});
120-
} else {
121-
model = await this.valueDAO.findOne({ scriptId: script?.id, key });
122-
}
123-
if (!model) {
124-
model = {
125-
id: 0,
126-
scriptId: script?.id || 0,
127-
storageName:
128-
(script?.metadata.storagename && script?.metadata.storagename[0]) ||
129-
"",
130-
key,
131-
value,
132-
createtime: new Date().getTime(),
133-
updatetime: 0,
134-
};
135-
} else {
136-
// 值未发生改变
137-
if (isEqual(model.value, value)) {
138-
return Promise.resolve(true);
116+
const valueTable = db.table("value");
117+
return db.transaction("rw", valueTable, async (tr) => {
118+
const valueDAO = new ValueDAO(tr.table("value"));
119+
if (script.metadata.storagename) {
120+
model = await valueDAO.findOne({
121+
storageName: script.metadata.storagename[0],
122+
key,
123+
});
124+
} else {
125+
model = await valueDAO.findOne({ scriptId: script.id, key });
139126
}
140-
oldValue = model.value;
141-
model.value = value;
142-
model.updatetime = new Date().getTime();
143-
}
144-
let changeNum = 0;
145-
// 更新缓存
146-
const cache = Cache.getInstance().get(
147-
CacheKey.scriptValue(script.id, script.metadata.storagename)
148-
);
149-
150-
if (value === undefined || value === null) {
151-
model.value = undefined;
152-
changeNum = await this.valueDAO.delete(model.id);
153-
if (cache) {
154-
delete cache[key];
127+
if (!model) {
128+
model = {
129+
id: 0,
130+
scriptId: script?.id || 0,
131+
storageName:
132+
(script?.metadata.storagename && script?.metadata.storagename[0]) ||
133+
"",
134+
key,
135+
value,
136+
createtime: new Date().getTime(),
137+
updatetime: 0,
138+
};
139+
} else {
140+
// 值未发生改变
141+
if (isEqual(model.value, value)) {
142+
return Promise.resolve(true);
143+
}
144+
oldValue = model.value;
145+
model.value = value;
146+
model.updatetime = new Date().getTime();
155147
}
156-
} else {
157-
changeNum = await this.valueDAO.save(model);
158-
if (cache) {
159-
cache[key] = model;
148+
let changeNum = 0;
149+
// 更新缓存
150+
const cache = Cache.getInstance().get(
151+
CacheKey.scriptValue(script.id, script.metadata.storagename)
152+
);
153+
154+
if (value === undefined || value === null) {
155+
model.value = undefined;
156+
changeNum = await valueDAO.delete(model.id);
157+
if (cache) {
158+
delete cache[key];
159+
}
160+
} else {
161+
changeNum = await valueDAO.save(model);
162+
if (cache) {
163+
cache[key] = model;
164+
}
165+
}
166+
if (changeNum <= 0) {
167+
return Promise.reject(new Error("value no change"));
160168
}
161-
}
162-
if (changeNum <= 0) {
163-
return Promise.reject(new Error("value no change"));
164-
}
165169

166-
const sendData: ValueUpdateData = {
167-
oldValue,
168-
sender,
169-
value: model,
170-
};
171-
// 广播value更新
172-
this.broadcast.broadcast({ tag: "all" }, "valueUpdate", sendData);
173-
174-
// 触发hook
175-
ValueManager.hook.trigger("upsert", model);
176-
return Promise.resolve(true);
170+
const sendData: ValueUpdateData = {
171+
oldValue,
172+
sender,
173+
value: model,
174+
};
175+
// 广播value更新
176+
this.broadcast.broadcast({ tag: "all" }, "valueUpdate", sendData);
177+
178+
// 触发hook
179+
ValueManager.hook.trigger("upsert", model);
180+
return Promise.resolve(true);
181+
});
177182
}
178183
}
179184

0 commit comments

Comments
 (0)