package jnpf.dmsBusinessOccupancy;
|
|
import org.mybatis.spring.SqlSessionTemplate;
|
import java.util.List;
|
import java.util.Objects;
|
|
/** Number lock precedes document/resource locks. Does not change any original expiry condition. */
|
public final class BusinessFileExpiryGate {
|
private final BusinessOccupancyTransactions transactions;
|
private final BusinessFileOccupancyCoordinator coordinator;
|
public BusinessFileExpiryGate(SqlSessionTemplate sessions) {
|
transactions = new BusinessOccupancyTransactions(sessions);
|
coordinator = new BusinessFileOccupancyCoordinator(sessions);
|
}
|
|
/** False means WAIT, never EXPIRED. Caller rereads deadline and executes in this transaction. */
|
public boolean tryEnter(String tenantId, String centerVersionId) {
|
Objects.requireNonNull(centerVersionId);
|
return transactions.execute(mapper -> {
|
List<BusinessFileTarget> before = mapper.expiryTargets(tenantId, centerVersionId);
|
if (before.isEmpty() && !mapper.hasCurrentBusinessReference(tenantId, centerVersionId)) {
|
// A CREATE can be center-effective before its resource projection commits.
|
// With no occupancy this still enters the original center/historical path.
|
String number=mapper.centerFileNumber(tenantId,centerVersionId);
|
if(number==null) return true;
|
if(!coordinator.tryEnterExpiry(tenantId,List.of(number))) return false;
|
return Objects.equals(number,mapper.centerFileNumber(tenantId,centerVersionId))
|
&& !mapper.hasCurrentBusinessReference(tenantId,centerVersionId);
|
}
|
if (before.size() != 1)
|
throw new IllegalStateException("到期文件当前业务映射异常,需核查映射");
|
BusinessFileTarget target = before.get(0);
|
if (!coordinator.tryEnterExpiry(tenantId, List.of(target.getFileNumber()))) return false;
|
// Discovery gives only the lock key; a mapping change must not redirect the expiry.
|
List<BusinessFileTarget> after = mapper.expiryTargets(tenantId, centerVersionId);
|
return before.equals(after);
|
});
|
}
|
}
|