你理解错了,我的意思是我有10万条账单,每500条一批去锁,可能有一批锁定失败,这一批是500条,但其实只有1条账单有问题,导致他锁定失败,我想精确定位这一条账单
时间: 2024-04-19 09:24:44 浏览: 125
非常抱歉误解了你的意思。如果你想精确定位导致批次锁定失败的账单,可以使用二分法逐渐缩小范围,直到只剩下一条账单。
以下是使用二分法进行精确定位的修改代码:
```java
import com.google.common.collect.Lists;
import java.util.List;
public class BillLockAlgorithm {
private static final int[] BATCH_SIZES = {100, 50, 10, 1};
public void lockBills(List<Bill> billList, int syncSettlementLockBillSize) {
List<List<Bill>> batchBillList = Lists.partition(billList, syncSettlementLockBillSize);
for (List<Bill> bills : batchBillList) {
try {
billTagApplyService.lockOrUnlockBill(bills, req.getProjectId(), true, LockTypeEnum.LOCK_TYPE_ENUM_16.getCode(), propertyUser, true);
} catch (Exception e) {
// 锁定失败尝试精确定位失败账单
locateFailedBill(bills);
}
}
}
private void locateFailedBill(List<Bill> bills) {
int start = 0;
int end = bills.size() - 1;
while (start < end) {
int mid = (start + end) / 2;
List<Bill> batch = bills.subList(mid, end + 1);
try {
billTagApplyService.lockOrUnlockBill(batch, req.getProjectId(), true, LockTypeEnum.LOCK_TYPE_ENUM_16.getCode(), propertyUser, true);
start = mid + 1; // 锁定成功,继续检查后半部分账单
} catch (Exception e) {
end = mid; // 锁定失败,缩小范围,继续检查前半部分账单
}
}
// 锁定失败的账单即为 bills.get(start)
Bill failedBill = bills.get(start);
recordFailedBill(failedBill);
}
private void recordFailedBill(Bill bill) {
// 记录失败的账单逻辑
}
}
```
在 `locateFailedBill` 方法中,我们使用二分法来缩小锁定失败账单的范围。我们将当前批次的账单列表 (`bills`) 分为两部分,并尝试锁定后半部分的账单。如果锁定成功,则说明失败的账单在后半部分,我们将范围缩小到后半部分。如果锁定失败,则说明失败的账单在前半部分,我们将范围缩小到前半部分。最终,当范围缩小到只剩下一条账单时,即为锁定失败的账单。
希望这次能够满足你的需求。记得根据你的实际情况进行适当的调整和错误处理。
阅读全文