面试题答案
一键面试- 数据库事务概述
- 在SQLite中,事务是一个不可分割的操作序列,要么全部成功执行,要么全部不执行。通过使用事务,可以确保在增、删、改操作时数据的一致性。
sqflite
插件提供了对事务操作的支持。
- 在SQLite中,事务是一个不可分割的操作序列,要么全部成功执行,要么全部不执行。通过使用事务,可以确保在增、删、改操作时数据的一致性。
- 插入操作(增)
- 假设我们有一个订单表
orders
和商品项表order_items
。订单表可能包含order_id
,order_date
等字段,商品项表可能包含item_id
,order_id
,product_name
,quantity
等字段。 - 示例代码如下:
- 假设我们有一个订单表
Future<void> insertOrderAndItems(Order order, List<OrderItem> items) async {
final Database db = await database;
await db.transaction((txn) async {
// 插入订单
int orderId = await txn.insert('orders', order.toMap());
// 插入商品项,关联订单ID
for (var item in items) {
item.orderId = orderId;
await txn.insert('order_items', item.toMap());
}
});
}
- 在上述代码中,通过
db.transaction
开启一个事务。先插入订单并获取生成的order_id
,然后使用该order_id
插入所有相关的商品项。如果任何一步失败,整个事务将回滚,不会出现部分数据插入成功的情况。
- 删除操作(删)
- 同样以订单和商品项为例,如果要删除一个订单及其所有相关商品项。
- 示例代码如下:
Future<void> deleteOrderAndItems(int orderId) async {
final Database db = await database;
await db.transaction((txn) async {
// 删除商品项
await txn.delete('order_items', where: 'order_id =?', whereArgs: [orderId]);
// 删除订单
await txn.delete('orders', where: 'order_id =?', whereArgs: [orderId]);
});
}
- 这里先删除与订单关联的商品项,再删除订单本身。如果删除商品项失败,事务回滚,订单也不会被删除,保证数据一致性。
- 更新操作(改)
- 假设要更新订单的日期,并同时更新部分商品项的数量。
- 示例代码如下:
Future<void> updateOrderAndItems(Order updatedOrder, List<OrderItem> updatedItems) async {
final Database db = await database;
await db.transaction((txn) async {
// 更新订单
await txn.update('orders', updatedOrder.toMap(), where: 'order_id =?', whereArgs: [updatedOrder.orderId]);
// 更新商品项
for (var item in updatedItems) {
await txn.update('order_items', item.toMap(), where: 'item_id =?', whereArgs: [item.itemId]);
}
});
}
- 通过事务确保订单和商品项的更新操作要么全部成功,要么全部失败,避免数据不一致。
总之,使用sqflite
插件的transaction
方法来包裹增、删、改操作,能有效地确保在处理复杂数据结构时数据的一致性。