面试题答案
一键面试1. MongoDB 事务安全性设计
1.1 事务概念
MongoDB 从 4.0 版本开始支持多文档事务,允许在多个文档操作中保持原子性、一致性、隔离性和持久性(ACID)。在电商场景中,订单创建、库存扣减、支付处理等操作可以放在一个事务中,确保要么所有操作都成功,要么都失败回滚。
1.2 事务实现步骤
- 开启事务:使用
startTransaction()
方法开启一个事务。 - 执行操作:在事务块内执行订单创建、库存扣减、支付处理等相关的数据库操作,如
insertOne
、updateOne
等方法。 - 提交事务:如果所有操作都成功,调用
commitTransaction()
方法提交事务,将所有操作持久化到数据库。 - 回滚事务:如果任何一个操作失败,调用
abortTransaction()
方法回滚事务,撤销所有已执行的操作。
1.3 代码示例(Node.js 与 MongoDB Node.js 驱动)
const { MongoClient } = require('mongodb');
async function processOrder(order, payment) {
const uri = "mongodb://localhost:27017";
const client = new MongoClient(uri);
try {
await client.connect();
const session = client.startSession();
session.startTransaction();
const ordersCollection = client.db('ecommerce').collection('orders');
const inventoryCollection = client.db('ecommerce').collection('inventory');
const paymentsCollection = client.db('ecommerce').collection('payments');
// 订单创建
await ordersCollection.insertOne(order, { session });
// 库存扣减
await inventoryCollection.updateOne(
{ productId: order.productId },
{ $inc: { quantity: -order.quantity } },
{ session }
);
// 支付处理
await paymentsCollection.insertOne(payment, { session });
await session.commitTransaction();
console.log('Order processed successfully');
} catch (error) {
console.error('Error processing order:', error);
} finally {
await client.close();
}
}
2. 角色权限控制方案
2.1 角色与权限设计原则
- 最小化原则:为每个角色分配完成其任务所需的最小权限集合,避免权限过度授予。
- 职责分离:不同角色之间的权限应该相互独立,确保一个角色不能执行其他角色的关键操作。
2.2 角色与权限定义
- 订单创建角色(OrderCreator):
- 权限:对
orders
集合具有insert
权限。
- 权限:对
- 库存管理角色(InventoryManager):
- 权限:对
inventory
集合具有update
权限。
- 权限:对
- 支付处理角色(PaymentProcessor):
- 权限:对
payments
集合具有insert
权限。
- 权限:对
2.3 权限控制实现
- 基于中间件的权限验证:在应用层,通过中间件在调用数据库操作前验证用户角色和权限。例如,在 Express.js 应用中:
const express = require('express');
const app = express();
// 模拟用户角色信息
const userRole = 'OrderCreator';
// 中间件验证权限
function checkPermission(role, allowedActions) {
return function (req, res, next) {
if (allowedActions.includes(userRole)) {
next();
} else {
res.status(403).send('Forbidden');
}
};
}
// 订单创建路由
app.post('/orders', checkPermission('OrderCreator', ['OrderCreator']), async (req, res) => {
// 执行订单创建逻辑
});
- MongoDB 内置角色与权限:利用 MongoDB 的内置角色,如
readWrite
、dbAdmin
等,并结合自定义角色来精细控制权限。可以通过createRole
命令创建自定义角色:
use ecommerce;
db.createRole({
role: "OrderCreator",
privileges: [
{
resource: { db: "ecommerce", collection: "orders" },
actions: ["insert"]
}
],
roles: []
});
3. 高性能与高可用性保障
3.1 高性能
- 索引优化:为常用查询字段创建索引,如订单的
orderId
、库存的productId
、支付的paymentId
等。可以使用createIndex
方法创建索引:
const inventoryCollection = client.db('ecommerce').collection('inventory');
await inventoryCollection.createIndex({ productId: 1 });
- 批量操作:尽量合并多个操作成批量操作,减少数据库交互次数。例如,在库存扣减时,可以批量更新多个商品的库存。
- 合理配置事务隔离级别:根据业务需求选择合适的事务隔离级别,默认的
readCommitted
隔离级别在大多数情况下能满足需求,避免不必要的锁争用。
3.2 高可用性
- 副本集:使用 MongoDB 副本集,由一个主节点和多个从节点组成。主节点处理写操作,从节点复制主节点的数据并可以处理读操作。如果主节点故障,副本集自动选举新的主节点,确保服务可用性。
- 自动故障转移:MongoDB 副本集内置自动故障转移机制,当主节点不可用时,从节点中的一个会被选举为新的主节点,继续提供服务。
- 负载均衡:结合应用层的负载均衡器(如 Nginx),将读请求均匀分配到各个从节点,减轻主节点压力,提高系统整体性能和可用性。