记一次开发中遇到副作用与幂等问题
问题代码:
private final ConcurrentHashMap<String, List<Region>> store = new ConcurrentHashMap<>();
@Override
public List<Region> tree(boolean province) {
String storeKey = "regions" + province;
List<Region> regions = store.computeIfAbsent(storeKey, key -> baseMapper.tree(province));
return ForestNodeMerger.merge(regions);
}
引用变量 regions 实际是 store 里保存的值。而 ForestNodeMerger.merge 方法产生副作用,改变了store 的状态。因此该方法不是幂等的。
等价的例子:
private static HashMap<String, List<Integer>> hm = new HashMap<>();
public static void addNumbers() {
ArrayList<Integer> list = new ArrayList<>();
list.add(3);
list.add(4);
list.add(5);
List<Integer> list1 = hm.computeIfAbsent("list", key -> list);
list1.add(6);
System.out.println(list1);
}
public static void main(String[] args) {
addNumbers();
addNumbers();
}
输出结果为:
[3, 4, 5, 6] [3, 4, 5, 6, 6]
解决方法
private final ConcurrentHashMap<String, List<Region>> store = new ConcurrentHashMap<>();
@Override
public List<Region> tree(boolean province) {
String storeKey = "regions" + province;
return store.computeIfAbsent(storeKey, key -> ForestNodeMerger.merge(baseMapper.tree(province)));
}
将可能产生副作用的代码合并,只在最开始产生副作用。因此该方法是幂等的。
2333
浙公网安备 33010602011771号