Dexie.js 事务管理详解
1. 什么是事务(Transaction)?
事务(Transaction)是一组数据库操作的集合,具有 ACID(原子性、一致性、隔离性、持久性) 的特性。Dexie.js 提供了对 IndexedDB 事务的封装,简化了事务管理,确保多个数据库操作要么全部成功,要么全部回滚,以保证数据的一致性。
2. Dexie.js 事务管理的核心概念
概念 | 说明 |
---|---|
db.transaction(mode, tables, callback) | Dexie 提供的事务管理 API,确保所有操作在同一事务中执行 |
事务模式 | readonly (只读),readwrite (读写) |
db.transaction() 内部自动管理事务 | 事务内的所有操作要么全部成功,要么回滚 |
await 关键字 | 确保事务中的所有数据库操作按顺序执行 |
try...catch | 捕获事务错误并执行回滚 |
db.table() | 在事务中获取某个表 |
3. Dexie.js 事务示例
3.1 创建数据库
import Dexie from "dexie";
// 初始化数据库
const db = new Dexie("MyDatabase");
// 定义数据库模式
db.version(1).stores({
users: "id, name, email",
orders: "id, userId, product, quantity"
});
3.2 事务示例:用户下订单
async function placeOrder(userId, product, quantity) {
try {
await db.transaction("rw", db.users, db.orders, async () => {
// 查询用户是否存在
const user = await db.users.get(userId);
if (!user) {
throw new Error("用户不存在,无法下订单!");
}
// 插入订单
await db.orders.add({
id: Date.now(), // 生成唯一订单ID
userId,
product,
quantity
});
console.log(`订单成功创建:用户 ${user.name} 购买 ${quantity} 个 ${product}`);
});
console.log("事务提交成功");
} catch (error) {
console.error("事务失败,已回滚:", error);
}
}
// 示例:用户下单
placeOrder(1, "Laptop", 2);
3.3 事务回滚示例
placeOrder(2, "Smartphone", 1);
控制台输出:
事务失败,已回滚: Error: 用户不存在,无法下订单!
✅ 事务回滚,数据库不会插入错误订单!
4. 事务中的多个操作
示例:用户购买多个商品
async function placeMultipleOrders(userId, orderList) {
try {
await db.transaction("rw", db.users, db.orders, async () => {
// 检查用户是否存在
const user = await db.users.get(userId);
if (!user) throw new Error("用户不存在");
// 遍历所有订单
for (let order of orderList) {
if (order.quantity > 5) {
throw new Error(`商品 ${order.product} 购买数量超限`);
}
// 插入订单
await db.orders.add({
id: Date.now() + Math.random(),
userId,
product: order.product,
quantity: order.quantity
});
console.log(`订单成功:${user.name} 购买 ${order.quantity} 个 ${order.product}`);
}
});
console.log("所有订单成功提交!");
} catch (error) {
console.error("事务失败,所有订单已回滚:", error);
}
}
// 示例:批量下单
placeMultipleOrders(1, [
{ product: "Laptop", quantity: 1 },
{ product: "Tablet", quantity: 3 },
{ product: "Smartphone", quantity: 6 } // ❌ 超出限制,导致整个事务回滚
]);
✅ 事务回滚,避免部分订单成功、部分失败的情况!
5. 事务中的并行与嵌套
5.1 并行操作
await Promise.all([
db.orders.add({ id: 201, userId: 1, product: "Keyboard", quantity: 1 }),
db.orders.add({ id: 202, userId: 1, product: "Mouse", quantity: 2 })
]);
注意:如果 Promise.all
内部有失败的操作,整个事务回滚!
5.2 事务嵌套
await db.transaction("rw", db.users, db.orders, async () => {
let user = await db.users.get(1);
user.lastOrder = Date.now();
await db.users.put(user);
await db.orders.add({ id: 203, userId: 1, product: "Monitor", quantity: 1 });
});
✅ 所有操作在同一事务中执行,确保数据一致性!
6. 总结
事务管理特性 | IndexedDB | Dexie.js |
---|---|---|
事务创建 | 手动创建 transaction | db.transaction() 自动管理 |
操作模式 | readonly , readwrite | rw (读写) |
错误处理 | 需监听 onerror | try-catch 直接捕获 |
回滚机制 | 需要手动处理 | 事务失败时自动回滚 |
多表事务 | 需手动管理 | 自动管理多个表 |
并行操作 | 复杂 | Promise.all() |
Dexie.js 通过自动管理事务、简化事务操作、支持 async/await,极大地提高了 IndexedDB 的可用性,是前端本地数据库管理的首选方案!🚀