MST

星途 面试题库

面试题:Python中MongoDB的事务处理及性能优化

在一个银行转账场景下,使用Python的pymongo库,假设存在两个集合'accounts'存储账户信息(结构:{'account_id': '123', 'balance': 1000}),'transactions'存储交易记录(结构:{'from_account': '123', 'to_account': '456', 'amount': 500, 'timestamp': '2023 - 10 - 01 12:00:00'})。请设计并实现一个原子性的转账操作,确保从一个账户扣除金额和向另一个账户增加金额以及记录交易这三个操作要么全部成功,要么全部失败。同时,针对高并发转账场景,提出至少3种性能优化的方案,并简述其原理。
10.8万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

原子性转账操作实现

import pymongo
from pymongo import MongoClient
from pymongo.write_concern import WriteConcern
from pymongo.read_concern import ReadConcern
from pymongo.read_preferences import ReadPreference


def transfer_money(from_account_id, to_account_id, amount):
    client = MongoClient()
    db = client['bank_db']
    accounts = db['accounts']
    transactions = db['transactions']

    with client.start_session() as session:
        session.start_transaction()
        try:
            # 检查转出账户余额是否足够
            from_account = accounts.find_one({'account_id': from_account_id}, session=session)
            if from_account['balance'] < amount:
                session.abort_transaction()
                return False

            # 扣除转出账户金额
            accounts.update_one(
                {'account_id': from_account_id},
                {'$inc': {'balance': -amount}},
                session=session
            )

            # 增加转入账户金额
            accounts.update_one(
                {'account_id': to_account_id},
                {'$inc': {'balance': amount}},
                session=session
            )

            # 记录交易
            transactions.insert_one(
                {
                    'from_account': from_account_id,
                    'to_account': to_account_id,
                    'amount': amount,
                    'timestamp': '2023 - 10 - 01 12:00:00'
                },
                session=session
            )

            session.commit_transaction()
            return True
        except Exception as e:
            session.abort_transaction()
            return False


高并发转账场景性能优化方案

  1. 索引优化
    • 原理:在accounts集合的account_id字段和transactions集合的from_accountto_account字段上创建索引。这样在高并发场景下,查询账户信息和插入交易记录时,数据库能够更快地定位到相应文档,减少查询时间,从而提高系统性能。例如,accounts.create_index('account_id')transactions.create_index('from_account')transactions.create_index('to_account')
  2. 读写分离
    • 原理:使用MongoDB的副本集功能,将读操作分配到副本节点上,主节点只负责写操作。在高并发转账场景下,大量的账户余额查询(读操作)可以分担到副本节点,减轻主节点压力,提高系统整体的并发处理能力。通过设置ReadPreference.SECONDARY_PREFERRED可以优先从副本节点读取数据。
  3. 批量操作
    • 原理:将多个转账操作合并成一个批量操作。例如,如果有多个用户同时进行转账,可以将这些转账操作的更新和插入语句合并,一次性发送到数据库执行,减少数据库的交互次数,从而提高性能。在Python中,可以利用pymongo的批量操作方法,如update_manyinsert_many
  4. 缓存机制
    • 原理:在应用层引入缓存,如Redis。在处理转账请求时,先从缓存中读取账户余额信息,如果缓存中没有则从数据库读取,并将读取到的信息写入缓存。在更新账户余额时,同时更新缓存。这样在高并发场景下,大部分读操作可以直接从缓存获取数据,减少对数据库的压力,提高响应速度。