Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,8 @@ public int addEntry(String path, int parentPathId) throws SQLException, Registry
if (log.isDebugEnabled()) {
log.debug("Failed to insert due to already exist in database : " + path);
}
// we have to be expecting an exception with the duplicate value for the path value
// which can be further checked from here..
pathId = getPathID(conn, path);
// Handle constraint violation by rolling back and retrying pathID lookup.
pathId = getPathIDAfterRollback(conn, path);
if (pathId > 0) {
success = true;
return pathId;
Expand Down Expand Up @@ -307,9 +306,8 @@ public int addEntry(JDBCDatabaseTransaction.ManagedRegistryConnection conn,
if (log.isDebugEnabled()) {
log.debug("Failed to insert due to already exist in database : " + path);
}
// we have to be expecting an exception with the duplicate value for the path value
// which can be further checked from here..
pathId = getPathID(conn, path);
// Handle constraint violation by rolling back and retrying pathID lookup.
pathId = getPathIDAfterRollback(conn, path);
if (pathId > 0) {
success = true;
return pathId;
Expand Down Expand Up @@ -540,4 +538,31 @@ public int getPathID(AbstractConnection conn, String path) throws SQLException {
}
return -1;
}

/**
* Retrieves the existing path ID after rolling back an aborted transaction
* caused by a constraint violation during concurrent path creation.
*
* @param conn the database connection in aborted transaction state
* @param path the path that caused the constraint violation
* @return the existing path ID if found, or -1 if not found
*/
private int getPathIDAfterRollback(AbstractConnection conn, String path) throws SQLException {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Log Improvement Suggestion No: 1

Suggested change
private int getPathIDAfterRollback(AbstractConnection conn, String path) throws SQLException {
private int getPathIDAfterRollback(AbstractConnection conn, String path) throws SQLException {
if (log.isDebugEnabled()) {
log.debug("Attempting to retrieve path ID after rollback for path: " + path);
}


try {
conn.rollback();
if (log.isDebugEnabled()) {
log.debug("Rolled back aborted transaction for path: " + path +
" for tenant: " + CurrentSession.getTenantId());
}
} catch (SQLException rollbackException) {
String msg = "Failed to rollback aborted transaction for path: " + path +
". " + rollbackException.getMessage();
log.error(msg, rollbackException);

// Re-throw to maintain error propagation.
throw rollbackException;
}
return getPathID(conn, path);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1166,48 +1166,63 @@ public static void setupMediaTypes(RegistryService registryService, int tenantId
}
}

/**
* Gets or creates a lock object for the specified tenant initialization.
* Uses String.intern() for memory-efficient synchronization.
*
* @param tenantId The ID of the tenant.
* @return the lock object for the specified tenant initialization.
*/
private static Object getTenantInitializationLock(int tenantId) {

return ("initializeTenant:" + tenantId).intern();
}

// Do tenant-specific initialization.
public static void initializeTenant(RegistryService registryService, int tenantId)
throws RegistryException {
try {
UserRegistry systemRegistry = registryService.getConfigSystemRegistry();
if (systemRegistry.getRegistryContext() != null) {
HandlerManager handlerManager =
systemRegistry.getRegistryContext()
.getHandlerManager();
if (handlerManager instanceof HandlerLifecycleManager) {
((HandlerLifecycleManager) handlerManager).init(tenantId);
}
}
systemRegistry =
registryService.getRegistry(CarbonConstants.REGISTRY_SYSTEM_USERNAME,
tenantId);
addMountCollection(systemRegistry);
registerMountPoints(systemRegistry, tenantId);
new RegistryCoreServiceComponent().setupMounts(registryService, tenantId);
setupMediaTypes(registryService, tenantId);
// We need to set the tenant ID for current session. Otherwise the
// underlying operations fails
public static void initializeTenant(RegistryService registryService, int tenantId) throws RegistryException {

// Synchronize on the specific tenant to prevent race conditions during tenant initialization.
synchronized (getTenantInitializationLock(tenantId)) {
try {
CurrentSession.setTenantId(tenantId);
RegistryContext registryContext = systemRegistry.getRegistryContext();
// Adding collection to store user profile information.
addUserProfileCollection(systemRegistry,
getAbsolutePath(registryContext,
registryContext.getProfilesPath()));
// Adding collection to store services.
addServiceStoreCollection(systemRegistry,
getAbsolutePath(registryContext,
registryContext.getServicePath()));
// Adding service configuration resources.
addServiceConfigResources(systemRegistry);
} finally {
CurrentSession.removeTenantId();
UserRegistry systemRegistry = registryService.getConfigSystemRegistry();
if (systemRegistry.getRegistryContext() != null) {
HandlerManager handlerManager =
systemRegistry.getRegistryContext()
.getHandlerManager();
if (handlerManager instanceof HandlerLifecycleManager) {
((HandlerLifecycleManager) handlerManager).init(tenantId);
}
}
systemRegistry =
registryService.getRegistry(CarbonConstants.REGISTRY_SYSTEM_USERNAME,
tenantId);
addMountCollection(systemRegistry);
registerMountPoints(systemRegistry, tenantId);
new RegistryCoreServiceComponent().setupMounts(registryService, tenantId);
setupMediaTypes(registryService, tenantId);
// We need to set the tenant ID for current session. Otherwise the
// underlying operations fails
try {
CurrentSession.setTenantId(tenantId);
RegistryContext registryContext = systemRegistry.getRegistryContext();
// Adding collection to store user profile information.
addUserProfileCollection(systemRegistry,
getAbsolutePath(registryContext,
registryContext.getProfilesPath()));
// Adding collection to store services.
addServiceStoreCollection(systemRegistry,
getAbsolutePath(registryContext,
registryContext.getServicePath()));
// Adding service configuration resources.
addServiceConfigResources(systemRegistry);
} finally {
CurrentSession.removeTenantId();
}
} catch (RegistryException e) {
log.error("Unable to initialize registry for tenant " + tenantId + ".", e);
throw new RegistryException("Unable to initialize registry for tenant " + tenantId +
".", e);
}
} catch (RegistryException e) {
log.error("Unable to initialize registry for tenant " + tenantId + ".", e);
throw new RegistryException("Unable to initialize registry for tenant " + tenantId +
".", e);
}
}

Expand Down