fix(auth): avoid gap locks when creating accounts
This commit is contained in:
@@ -9,6 +9,7 @@ import jakarta.annotation.Resource;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import com.baiyue.common.audit.BusinessAudit;
|
||||
|
||||
import java.util.Locale;
|
||||
@@ -63,7 +64,9 @@ public class AccountManagementService {
|
||||
String appCode = request.appCode() == null ? "MERCHANT"
|
||||
: request.appCode().trim().toUpperCase(Locale.ROOT);
|
||||
validateScope(appCode, request.tenantId());
|
||||
AuthAccount existing = repository.findById(request.accountId());
|
||||
// Locking a missing key takes an InnoDB gap lock and can deadlock
|
||||
// unrelated account inserts. The unique indexes arbitrate creation.
|
||||
AuthAccount existing = repository.findCurrentById(request.accountId());
|
||||
if (existing != null) {
|
||||
if (sameIdentity(existing, request, appCode)) return summary(existing);
|
||||
throw new BizException(ResultCode.CONFLICT, "认证账号标识已被其他成员使用");
|
||||
@@ -88,7 +91,13 @@ public class AccountManagementService {
|
||||
account.setDefaultMembershipId(request.membershipId());
|
||||
account.setDefaultAppCode(appCode);
|
||||
account.setDeleted(0);
|
||||
repository.insert(account);
|
||||
try {
|
||||
repository.insert(account);
|
||||
} catch (DuplicateKeyException duplicate) {
|
||||
AuthAccount winner = repository.findById(request.accountId());
|
||||
if (winner != null && sameIdentity(winner, request, appCode)) return summary(winner);
|
||||
throw new BizException(ResultCode.CONFLICT, "认证账号标识或登录账号已被使用");
|
||||
}
|
||||
return summary(account);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user