定义
实现失败原子性的方法
不可变对象
- 原子性是不可变对象所固有的,因为它们的状态在创建后无法更改。
示例:
// exemplo simplificado de um objeto imutável public final class immutableobject { private final int value; public immutableobject(int value) { this.value = value; } public int getvalue() { return value; } }
操作前参数验证
- 修改对象前检查参数的有效性。
示例:
// verificação de estado em um método stack.pop() public object pop() { if (size == 0) { throw new illegalstateexception("stack is empty"); } object result = elements[--size]; elements[size] = null; // evitar vazamento de memória return result; }
操作排序
- 在更改对象的状态之前确保容易发生故障的部分发生。
示例:
// adicionando elemento em treemap (simulação) public void addelement(treemap<string, integer> map, string key, integer value) { if (key == null || value == null) { throw new illegalargumentexception("key or value is null"); } map.put(key, value); // falhas na comparação ocorrem antes de alterar a estrutura }
临时副本
- 对对象的临时副本执行操作,只有操作成功后才替换原始对象。
示例:
// simulação de operação em cópia temporária public void sortlist(list<integer> list) { list<integer> temp = new arraylist<>(list); try { collections.sort(temp); list.clear(); list.addall(temp); } catch (exception e) { // a lista original permanece intacta } }
恢复代码
- 失败时将对象状态恢复到原始状态。
- 通常用于持久数据结构。
示例:
public void updateRecord(Database db, Record record) { Record backup = db.getRecord(record.getId()); // Fazer backup try { db.update(record); } catch (Exception e) { db.update(backup); // Reverter em caso de falha } }
值得注意的例外
- 不可修复的错误,例如 concurrentmodificationexception 或 assertionerror:
- 失败原子性既不能得到保证,也没有必要。
成本和复杂性
- 实现故障原子性并不总是可行的,特别是在复杂或高成本的操作中。
良好实践
- 如果方法不能保证原子性,则必须在失败后记录对象的状态。
最终总结
- 建议:作为方法规范一部分的每个异常都必须使对象处于与调用之前相同的状态。
- 例外:当这不可能或不可行时,api 文档应该清楚地说明对对象状态的影响。