From dac5c2b511bcd6b543e63bede7eb5a5963d72dd5 Mon Sep 17 00:00:00 2001 From: charitha Date: Mon, 18 May 2020 09:22:23 +0530 Subject: [PATCH] Fix deadlock in device application list update --- .../mgt/core/dao/impl/AbstractDeviceDAOImpl.java | 3 ++- .../mgt/core/dao/impl/ApplicationDAOImpl.java | 15 ++++----------- .../core/operation/mgt/OperationManagerImpl.java | 10 +++++++--- .../src/main/resources/dbscripts/cdm/mssql.sql | 11 +++++++++-- .../src/main/resources/dbscripts/cdm/mysql.sql | 2 ++ 5 files changed, 24 insertions(+), 17 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java index 1c6ebebae3..ff56439f04 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java @@ -2650,7 +2650,8 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { int deviceCount = 0; try { conn = this.getConnection(); - String sql = "SELECT COUNT(e.DEVICE_ID) AS DEVICE_COUNT FROM DM_ENROLMENT e WHERE STATUS != 'REMOVED'"; + String sql = "SELECT COUNT(e.DEVICE_ID) AS DEVICE_COUNT FROM DM_ENROLMENT e WHERE STATUS = 'ACTIVE' " + + "OR STATUS = 'UNREACHABLE'"; stmt = conn.prepareStatement(sql); ResultSet rs = stmt.executeQuery(); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/ApplicationDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/ApplicationDAOImpl.java index aa44f0996a..5a89b613be 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/ApplicationDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/ApplicationDAOImpl.java @@ -88,7 +88,7 @@ public class ApplicationDAOImpl implements ApplicationDAO { conn = this.getConnection(); stmt = conn.prepareStatement("UPDATE DM_APPLICATION SET NAME = ?, PLATFORM = ?, CATEGORY = ?, " + "VERSION = ?, TYPE = ?, LOCATION_URL = ?, IMAGE_URL = ?, MEMORY_USAGE = ?, IS_ACTIVE = ? " + - "WHERE APP_IDENTIFIER = ? AND DEVICE_ID = ? AND ENROLMENT_ID = ? AND TENANT_ID = ?"); + "WHERE ID = ?"); for (Application application : applications) { stmt.setString(1, application.getName()); @@ -100,10 +100,7 @@ public class ApplicationDAOImpl implements ApplicationDAO { stmt.setString(7, application.getImageUrl()); stmt.setInt(8, application.getMemoryUsage()); stmt.setBoolean(9, application.isActive()); - stmt.setString(10, application.getApplicationIdentifier()); - stmt.setInt(11, deviceId); - stmt.setInt(12, enrolmentId); - stmt.setInt(13, tenantId); + stmt.setInt(10, application.getId()); stmt.addBatch(); } stmt.executeBatch(); @@ -123,14 +120,10 @@ public class ApplicationDAOImpl implements ApplicationDAO { try { conn = this.getConnection(); conn.setAutoCommit(false); - stmt = conn.prepareStatement("DELETE FROM DM_APPLICATION WHERE APP_IDENTIFIER = ? AND DEVICE_ID = ? " + - "AND ENROLMENT_ID = ? AND TENANT_ID = ?"); + stmt = conn.prepareStatement("DELETE FROM DM_APPLICATION WHERE ID = ?"); for (Application app : apps) { - stmt.setString(1, app.getApplicationIdentifier()); - stmt.setInt(2, deviceId); - stmt.setInt(3, enrolmentId); - stmt.setInt(4, tenantId); + stmt.setInt(1, app.getId()); stmt.addBatch(); } stmt.executeBatch(); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/OperationManagerImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/OperationManagerImpl.java index ca7659f1e3..8620657a18 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/OperationManagerImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/OperationManagerImpl.java @@ -834,13 +834,14 @@ public class OperationManagerImpl implements OperationManager { public void updateOperation(int enrolmentId, Operation operation, DeviceIdentifier deviceId) throws OperationManagementException { int operationId = operation.getId(); + boolean isOperationUpdated = false; try { OperationManagementDAOFactory.beginTransaction(); if (operation.getStatus() != null) { int failAttempts = 0; while (true) { try { - operationDAO.updateOperationStatus(enrolmentId, operationId, + isOperationUpdated = operationDAO.updateOperationStatus(enrolmentId, operationId, org.wso2.carbon.device.mgt.core.dto.operation.mgt. Operation.Status.valueOf(operation.getStatus(). toString())); @@ -865,7 +866,10 @@ public class OperationManagerImpl implements OperationManager { } } } - if (operation.getOperationResponse() != null) { + if (!isOperationUpdated) { + log.warn("Operation " + operationId + "'s status is not updated"); + } + if (isOperationUpdated && operation.getOperationResponse() != null) { OperationMonitoringTaskConfig operationMonitoringTaskConfig = DeviceManagementDataHolder .getInstance().getDeviceManagementProvider().getDeviceMonitoringConfig(deviceId.getType()); List monitoringOperations = operationMonitoringTaskConfig.getMonitoringOperation(); @@ -901,7 +905,7 @@ public class OperationManagerImpl implements OperationManager { } } OperationResponseMeta responseMeta = null; - if (operation.getOperationResponse() != null) { + if (isOperationUpdated && operation.getOperationResponse() != null) { int failAttempts = 0; while (true) { try { diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql index 6ba14be3d2..5f437350e5 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql @@ -182,6 +182,9 @@ CREATE TABLE DM_DEVICE_OPERATION_RESPONSE ( DM_ENROLMENT_OP_MAPPING (ID) ON DELETE NO ACTION ON UPDATE NO ACTION ); +IF NOT EXISTS (SELECT * FROM SYS.INDEXES WHERE NAME = 'IDX_DM_RES_RT' AND OBJECT_ID = OBJECT_ID('DM_DEVICE_OPERATION_RESPONSE')) +CREATE INDEX IDX_DM_RES_RT ON DM_DEVICE_OPERATION_RESPONSE(RECEIVED_TIMESTAMP); + IF NOT EXISTS (SELECT * FROM SYS.INDEXES WHERE NAME = 'IDX_ENID_OPID' AND OBJECT_ID = OBJECT_ID('DM_DEVICE_OPERATION_RESPONSE')) CREATE INDEX IDX_ENID_OPID ON DM_DEVICE_OPERATION_RESPONSE(OPERATION_ID, ENROLMENT_ID); @@ -190,11 +193,12 @@ CREATE INDEX IDX_DM_EN_OP_MAP_RES ON DM_DEVICE_OPERATION_RESPONSE(EN_OP_MAP_ID); IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[DM_DEVICE_OPERATION_RESPONSE_LARGE]') AND TYPE IN (N'U')) CREATE TABLE DM_DEVICE_OPERATION_RESPONSE_LARGE ( - ID INTEGER IDENTITY(1,1) NOT NULL, + ID INTEGER NOT NULL, OPERATION_ID INTEGER NOT NULL, EN_OP_MAP_ID INTEGER NOT NULL, OPERATION_RESPONSE VARBINARY(MAX) DEFAULT NULL, - RECEIVED_TIMESTAMP DATETIME2 DEFAULT NULL + RECEIVED_TIMESTAMP DATETIME2 DEFAULT NULL, + DEVICE_IDENTIFICATION VARCHAR(300) DEFAULT NULL PRIMARY KEY (ID), CONSTRAINT FK_DM_DEVICE_OPERATION_RESP_LARGE_OPERATION FOREIGN KEY (OPERATION_ID) REFERENCES DM_OPERATION (ID) ON DELETE NO ACTION ON UPDATE NO ACTION, @@ -419,6 +423,9 @@ CREATE TABLE DM_APPLICATION ( DM_ENROLMENT (ID) ON DELETE NO ACTION ON UPDATE NO ACTION ); +IF NOT EXISTS (SELECT * FROM SYS.INDEXES WHERE NAME = 'IDX_DM_APPLICATION' AND OBJECT_ID = OBJECT_ID('DM_APPLICATION')) +CREATE INDEX IDX_DM_APPLICATION ON DM_APPLICATION(DEVICE_ID, ENROLMENT_ID, TENANT_ID); + -- POLICY RELATED TABLES FINISHED -- -- POLICY AND DEVICE GROUP MAPPING -- diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql index 90c4e8a00d..dceb96f4e8 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql @@ -439,6 +439,8 @@ CREATE TABLE IF NOT EXISTS DM_APPLICATION ( DM_ENROLMENT (ID) ON DELETE NO ACTION ON UPDATE NO ACTION )ENGINE = InnoDB; +CREATE INDEX IDX_DM_APPLICATION ON DM_APPLICATION(DEVICE_ID, ENROLMENT_ID, TENANT_ID); + -- END OF POLICY RELATED TABLES -- -- POLICY AND DEVICE GROUP MAPPING --