You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Brightway 2.5是否支持同一数据库的并发修改操作?

Brightway 2.5 数据库并发修改问题解决方案

问题背景

尝试在Brightway 2.5中并行创建同一Ecoinvent数据库的新活动/交换,已设置bd.projects.read_only=False,但持续遇到database is locked或LockError,堆栈跟踪如下:

File "/Users/shantanu/repos/carbontrail-brightway/ef_module.py", line 490, in create_location_specific_activity
new_activity = original_activity.copy()
^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/shantanu/anaconda3/lib/python3.11/site-packages/bw2data/project.py", line 446, in writable_project
return wrapped(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/shantanu/anaconda3/lib/python3.11/site-packages/bw2data/backends/proxies.py", line 446, in copy
activity.save()
File "/Users/shantanu/anaconda3/lib/python3.11/site-packages/bw2data/project.py", line 446, in writable_project
return wrapped(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/shantanu/anaconda3/lib/python3.11/site-packages/bw2data/backends/proxies.py", line 287, in save
IndexManager(Database(self["database"]).filename).update_dataset(self._data)
File "/Users/shantanu/anaconda3/lib/python3.11/site-packages/bw2data/search/indices.py", line 50, in update_dataset
writer = self.get().writer()
^^^^^^^^^^^^^^^^^^^
File "/Users/shantanu/anaconda3/lib/python3.11/site-packages/whoosh/index.py", line 464, in writer
return SegmentWriter(self, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/shantanu/anaconda3/lib/python3.11/site-packages/whoosh/writing.py", line 515, in __init__
raise LockError
whoosh.index.LockError

核心结论

Brightway 2.x不支持同一数据库的并发写入操作,原因如下:

  1. 搜索索引依赖Whoosh库,Whoosh的索引写操作采用排他锁机制,同一时间仅允许一个写进程/线程;
  2. 默认数据库后端使用SQLite,SQLite的写操作同样是排他锁,无法支持多写者并发。
    设置bd.projects.read_only=False仅解除项目只读限制,不改变数据库和索引的并发锁机制。

可行解决方案

  • 优先使用批量写入:
    收集所有待创建/修改的活动对象,一次性写入数据库,避免多次锁竞争。示例代码:

    import brightway2 as bw
    
    # 在内存中批量生成新活动
    new_activities = []
    for original in original_activities:
        new_activity = original.copy()
        # 执行活动修改逻辑(如设置位置、调整交换项等)
        new_activities.append(new_activity)
    
    # 批量写入目标数据库
    bw.Database("ecoinvent").write(new_activities)
    

    这种方式仅需获取一次锁,效率远高于并行单条写入。

  • 手动添加全局互斥锁:
    若必须保留并行逻辑,需在写操作外包裹全局锁,确保同一时间仅一个进程/线程执行写操作:

    from multiprocessing import Lock
    import brightway2 as bw
    
    # 多进程场景使用跨进程锁,线程场景可替换为threading.Lock
    db_write_lock = Lock()
    
    def create_location_specific_activity(original_activity):
        with db_write_lock:
            new_activity = original_activity.copy()
            # 执行活动修改逻辑
            new_activity.save()
    

    注意:多进程场景必须使用跨进程锁实现,线程锁无法跨进程生效。

  • 数据库副本拆分(可选):
    为每个并行任务创建独立的数据库副本,各自完成修改后再合并结果。此方案复杂度较高,适合大规模并行且合并成本低的场景。

内容的提问来源于stack exchange,提问作者kodr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 15:57:39