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

处理异常时如何避免代码部分执行?Java文本冒险拾取操作原子性问题

文字冒险游戏take操作原子性实现方案
  • 方案1:前置校验优先执行
    先调用两个操作的校验接口确认可执行,全部通过后再执行实际变更,从根源上避免中途失败的问题。适合Location和Inventory类可扩展校验方法的场景。
    示例代码:
public void take(Item item) throws ActionException {
    // 先做所有前置校验,不执行实际变更
    if (!location.canRemove(item)) {
        throw new ActionException("物品不在当前位置,无法拾取");
    }
    if (!inventory.canAdd(item)) {
        throw new ActionException("背包容量不足或物品无法拾取");
    }
    // 校验全部通过后执行实际操作
    location.remove(item);
    inventory.add(item);
}
  • 方案2:异常捕获+回滚机制
    如果现有类没有提供单独的校验方法,可以用try-catch包裹后续操作,失败时回滚已执行的步骤。需要保证回滚操作本身的稳定性,避免回滚也失败导致更严重的问题。
    示例代码:
public void take(Item item) throws ActionException {
    location.remove(item);
    try {
        inventory.add(item);
    } catch (ActionException e) {
        // 拾取失败,把物品放回原位置回滚
        location.add(item);
        // 重新抛出原异常给上层处理
        throw e;
    }
}
  • 方案3:通用事务封装(适合多操作原子性场景多的项目)
    如果项目中存在大量需要多步原子执行的逻辑(比如交易、道具合成等),可以抽象事务操作接口统一管理:
interface TransactionalAction {
    void execute() throws ActionException;
    void rollback();
}

// 移除物品操作实现类
class RemoveItemAction implements TransactionalAction {
    private Location location;
    private Item item;
    // 构造方法省略
    public void execute() throws ActionException {
        location.remove(item);
    }
    public void rollback() {
        location.add(item);
    }
}

// 添加物品操作实现类
class AddItemAction implements TransactionalAction {
    private Inventory inventory;
    private Item item;
    // 构造方法省略
    public void execute() throws ActionException {
        inventory.add(item);
    }
    public void rollback() {
        inventory.remove(item);
    }
}

// 最终执行逻辑
public void take(Item item) throws ActionException {
    List<TransactionalAction> actions = Arrays.asList(
        new RemoveItemAction(location, item),
        new AddItemAction(inventory, item)
    );
    int executedCount = 0;
    try {
        for (TransactionalAction action : actions) {
            action.execute();
            executedCount++;
        }
    } catch (ActionException e) {
        // 逆序回滚已执行的操作
        for (int i = executedCount - 1; i >= 0; i--) {
            actions.get(i).rollback();
        }
        throw e;
    }
}

补充说明:如果拾取操作的失败概率中,背包不可拾取的概率远高于物品不存在的概率,可以调整执行顺序,先执行inventory.add相关操作再执行location.remove,减少回滚触发的概率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 18:57:02