MST

星途 面试题库

面试题:MongoDB事务中增删改查结合的原子性保证问题

假设有两个集合'orders'和'products','orders'记录订单信息,结构为{order_id: 'string', product_id: 'string', quantity: 'number'},'products'记录商品库存信息,结构为{product_id: 'string', stock: 'number'}。在一个事务中,要插入一条新订单记录,同时减少对应商品的库存数量。如果在插入订单后,减少库存操作失败,如何保证事务回滚,确保数据的一致性?请详细说明实现思路并写出相关代码。
27.2万 热度难度
数据库MongoDB

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 开启事务,确保后续操作都在一个事务环境内。
  2. 插入新订单记录到 orders 集合。
  3. 根据订单中的 product_idproducts 集合中找到对应的商品,并减少其库存数量。
  4. 如果在减少库存操作时失败,回滚整个事务,以保证数据的一致性。
  5. 如果所有操作都成功,提交事务。

代码示例(以Python + MongoDB为例)

import pymongo
from pymongo import MongoClient

# 连接数据库
client = MongoClient('mongodb://localhost:27017/')
db = client['your_database']
orders_collection = db['orders']
products_collection = db['products']

def create_order_and_update_stock(order_id, product_id, quantity):
    session = client.start_session()
    session.start_transaction()
    try:
        # 插入新订单记录
        order = {'order_id': order_id, 'product_id': product_id, 'quantity': quantity}
        orders_collection.insert_one(order, session=session)

        # 减少对应商品的库存数量
        result = products_collection.update_one(
            {'product_id': product_id},
            {'$inc': {'stock': -quantity}},
            session=session
        )
        if result.modified_count == 0:
            raise Exception("库存不足或商品不存在")

        session.commit_transaction()
        print("订单创建和库存更新成功")
    except Exception as e:
        session.abort_transaction()
        print(f"操作失败,事务回滚: {e}")
    finally:
        session.end_session()


# 调用示例
create_order_and_update_stock('order1', 'product1', 5)

上述代码实现了在插入订单记录并更新库存的过程中,若更新库存失败,回滚整个事务以保证数据一致性。如果使用其他数据库,实现方式会有所不同,但基本思路是一致的。例如在MySQL中,可以使用 BEGIN, COMMIT, ROLLBACK 语句来控制事务。以下是MySQL的示例代码(假设使用Python的 mysql - connector - python 库):

import mysql.connector

# 连接数据库
mydb = mysql.connector.connect(
    host="localhost",
    user="your_user",
    password="your_password",
    database="your_database"
)

mycursor = mydb.cursor()


def create_order_and_update_stock(order_id, product_id, quantity):
    try:
        mydb.start_transaction()
        # 插入新订单记录
        sql = "INSERT INTO orders (order_id, product_id, quantity) VALUES (%s, %s, %s)"
        val = (order_id, product_id, quantity)
        mycursor.execute(sql, val)

        # 减少对应商品的库存数量
        sql = "UPDATE products SET stock = stock - %s WHERE product_id = %s"
        val = (quantity, product_id)
        mycursor.execute(sql, val)

        if mycursor.rowcount == 0:
            raise Exception("库存不足或商品不存在")

        mydb.commit()
        print("订单创建和库存更新成功")
    except Exception as e:
        mydb.rollback()
        print(f"操作失败,事务回滚: {e}")


# 调用示例
create_order_and_update_stock('order1', 'product1', 5)

在MySQL中,使用 start_transaction() 开启事务,commit() 提交事务,rollback() 回滚事务。同样,在其他数据库(如Oracle、PostgreSQL等)中,事务控制的语法和操作方式会有所差异,但确保数据一致性的基本原理不变。