Hi All,

I have implemented state life cycle to prevent concurrent API call from
agent to pending operations endpoint. However issue is still appearing. I
have tested the same scenario with Update 10 and was able to reproduce the
issue with Update 10 pack also.

However as I figured out, we are sending FCM notification before updating
operation mapping table[1]. Due to that device received FCM notification in
realtime as same as it is being added to the Operations DB in the server.
So there is chance to a raise condition and as a result, we are observing
above exception. So we might need to send FCM notification after updating
Operation Mapping in order to prevent that. WDYT?

[1]
https://github.com/wso2/carbon-device-mgt/blob/master/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/OperationManagerImpl.java#L195

Thanks & Regards,
/charithag

On Tue, Jan 23, 2018 at 2:34 PM, Charitha Goonetilleke <charit...@wso2.com>
wrote:

> Hi All,
>
> I was able to figure out the root cause for the issue. As Geeth and Rasika
> pointed out this is happening due to concurrent insert and update query
> executions. The root cause for this is calling pending operations endpoint
> more than once from a single android device at a given time. Due to that
> concurrent insert and update happen in the DB level. Ideally a device
> should not call pending operations endpoint simultaneously. But as device
> may receive multiple FCM notifications within fractions of seconds, it is
> triggering pending operation calls per notification.
>
> So I'm now implementing a state machine to avoid that raise condition.
>
> Thanks & Regards,
> /charithag
>
> On Tue, Jan 23, 2018 at 2:14 PM, Rasika Perera <rasi...@wso2.com> wrote:
>
>> ​Hi All,
>>
>> This error has raised since two threads trying to ​update the DB with
>> following requirements;
>>
>> Thread #1
>> waiting to lock PUBLIC.*DM_ENROLMENT_OP_MAPPING* while
>> locking PUBLIC.*DM_OPERATION* (exclusive), PUBLIC.*DM_COMMAND_OPERATION*
>> (exclusive).
>>
>> Thread #2
>> waiting to lock PUBLIC.DM_OPERATION while
>> locking PUBLIC.*DM_ENROLMENT_OP_MAPPING* (exclusive), PUBLIC.
>> *DM_DEVICE_OPERATION_RESPONSE* (exclusive).";
>>
>> I noticed we are already using ";LOCK_TIMEOUT=60000" (60sec) H2 DB
>> parameter which would allow sometime to continue the thread and do the DB
>> update.
>>
>> Hence, this might happen when you are holding the debug pointer in
>> updateOperation() method or in a state where device responses burst occurs.
>> However the latter case is very rare on other DBs(other than embedded H2).
>> We can even minimize the chance for a such issue implementing a LOCK for
>> calling updateOperation method(might affect the performance). WDYT?
>>
>> Best Regards,
>> ~Rasika
>>
>> On Tue, Jan 23, 2018 at 12:39 PM, Charitha Goonetilleke <
>> charit...@wso2.com> wrote:
>>
>>> Hi All,
>>>
>>> I have encountered following exception intermittently on IoTS Update 11,
>>> when testing with Android device.
>>>
>>> [2018-01-23 12:19:51,077] [IoT-Core] ERROR -
>>> {org.wso2.carbon.mdm.services.android.services.impl.DeviceManagementServiceImpl}
>>> Issue in retrieving operation management service instance
>>> org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException:
>>> Error occurred while updating the operation: 90 status:COMPLETED
>>> at org.wso2.carbon.device.mgt.core.operation.mgt.OperationManag
>>> erImpl.updateOperation(OperationManagerImpl.java:551)
>>> at org.wso2.carbon.device.mgt.core.service.DeviceManagementProv
>>> iderServiceImpl.updateOperation(DeviceManagementProviderServ
>>> iceImpl.java:1426)
>>> at org.wso2.carbon.mdm.services.android.util.AndroidDeviceUtils
>>> .updateOperation(AndroidDeviceUtils.java:211)
>>> at org.wso2.carbon.mdm.services.android.services.impl.DeviceMan
>>> agementServiceImpl.updateOperations(DeviceManagementServiceI
>>> mpl.java:184)
>>> at org.wso2.carbon.mdm.services.android.services.impl.DeviceMan
>>> agementServiceImpl.getPendingOperations(DeviceManagementServ
>>> iceImpl.java:139)
>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce
>>> ssorImpl.java:62)
>>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe
>>> thodAccessorImpl.java:43)
>>> at java.lang.reflect.Method.invoke(Method.java:498)
>>> at org.apache.cxf.service.invoker.AbstractInvoker.performInvoca
>>> tion(AbstractInvoker.java:188)
>>> at org.apache.cxf.service.invoker.AbstractInvoker.invoke(Abstra
>>> ctInvoker.java:104)
>>> at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:204)
>>> at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:101)
>>> at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(S
>>> erviceInvokerInterceptor.java:58)
>>> at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleM
>>> essage(ServiceInvokerInterceptor.java:94)
>>> at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(Phase
>>> InterceptorChain.java:272)
>>> at org.apache.cxf.transport.ChainInitiationObserver.onMessage(C
>>> hainInitiationObserver.java:121)
>>> at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke
>>> (AbstractHTTPDestination.java:249)
>>> at org.apache.cxf.transport.servlet.ServletController.invokeDes
>>> tination(ServletController.java:248)
>>> at org.apache.cxf.transport.servlet.ServletController.invoke(Se
>>> rvletController.java:222)
>>> at org.apache.cxf.transport.servlet.ServletController.invoke(Se
>>> rvletController.java:153)
>>> at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(
>>> CXFNonSpringServlet.java:171)
>>> at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleR
>>> equest(AbstractHTTPServlet.java:289)
>>> at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPut(A
>>> bstractHTTPServlet.java:226)
>>> at javax.servlet.http.HttpServlet.service(HttpServlet.java:653)
>>> at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service
>>> (AbstractHTTPServlet.java:265)
>>> at org.apache.catalina.core.ApplicationFilterChain.internalDoFi
>>> lter(ApplicationFilterChain.java:303)
>>> at org.apache.catalina.core.ApplicationFilterChain.doFilter(App
>>> licationFilterChain.java:208)
>>> at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilte
>>> r.java:52)
>>> at org.apache.catalina.core.ApplicationFilterChain.internalDoFi
>>> lter(ApplicationFilterChain.java:241)
>>> at org.apache.catalina.core.ApplicationFilterChain.doFilter(App
>>> licationFilterChain.java:208)
>>> at org.wso2.carbon.mdm.services.android.util.ApiOriginFilter.do
>>> Filter(ApiOriginFilter.java:33)
>>> at org.apache.catalina.core.ApplicationFilterChain.internalDoFi
>>> lter(ApplicationFilterChain.java:241)
>>> at org.apache.catalina.core.ApplicationFilterChain.doFilter(App
>>> licationFilterChain.java:208)
>>> at org.apache.catalina.core.StandardWrapperValve.invoke(Standar
>>> dWrapperValve.java:218)
>>> at org.apache.catalina.core.StandardContextValve.invoke(Standar
>>> dContextValve.java:110)
>>> at org.apache.catalina.authenticator.AuthenticatorBase.invoke(A
>>> uthenticatorBase.java:506)
>>> at org.apache.catalina.core.StandardHostValve.invoke(StandardHo
>>> stValve.java:169)
>>> at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorRepo
>>> rtValve.java:103)
>>> at org.wso2.carbon.tomcat.ext.valves.CompositeValve.continueInv
>>> ocation(CompositeValve.java:99)
>>> at org.wso2.carbon.tomcat.ext.valves.CarbonTomcatValve$1.invoke
>>> (CarbonTomcatValve.java:47)
>>> at org.wso2.carbon.webapp.mgt.TenantLazyLoaderValve.invoke(Tena
>>> ntLazyLoaderValve.java:57)
>>> at org.wso2.carbon.webapp.authenticator.framework.WebappAuthent
>>> icationValve.processRequest(WebappAuthenticationValve.java:151)
>>> at org.wso2.carbon.webapp.authenticator.framework.WebappAuthent
>>> icationValve.invoke(WebappAuthenticationValve.java:69)
>>> at org.wso2.carbon.tomcat.ext.valves.TomcatValveContainer.invok
>>> eValves(TomcatValveContainer.java:47)
>>> at org.wso2.carbon.tomcat.ext.valves.CompositeValve.invoke(Comp
>>> ositeValve.java:62)
>>> at org.wso2.carbon.tomcat.ext.valves.CarbonStuckThreadDetection
>>> Valve.invoke(CarbonStuckThreadDetectionValve.java:159)
>>> at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogVa
>>> lve.java:962)
>>> at org.wso2.carbon.tomcat.ext.valves.CarbonContextCreatorValve.
>>> invoke(CarbonContextCreatorValve.java:57)
>>> at org.apache.catalina.core.StandardEngineValve.invoke(Standard
>>> EngineValve.java:116)
>>> at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAd
>>> apter.java:445)
>>> at org.apache.coyote.http11.AbstractHttp11Processor.process(Abs
>>> tractHttp11Processor.java:1115)
>>> at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler
>>> .process(AbstractProtocol.java:637)
>>> at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun
>>> (NioEndpoint.java:1770)
>>> at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(N
>>> ioEndpoint.java:1729)
>>> at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPool
>>> Executor.java:1142)
>>> at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoo
>>> lExecutor.java:617)
>>> at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.r
>>> un(TaskThread.java:61)
>>> at java.lang.Thread.run(Thread.java:745)
>>> Caused by: 
>>> org.wso2.carbon.device.mgt.core.operation.mgt.dao.OperationManagementDAOException:
>>> Error occurred while inserting operation response
>>> at org.wso2.carbon.device.mgt.core.operation.mgt.dao.impl.Gener
>>> icOperationDAOImpl.addOperationResponse(GenericOperationDAOI
>>> mpl.java:213)
>>> at org.wso2.carbon.device.mgt.core.operation.mgt.OperationManag
>>> erImpl.updateOperation(OperationManagerImpl.java:544)
>>> ... 58 more
>>> Caused by: org.h2.jdbc.JdbcSQLException: Deadlock detected. The current
>>> transaction was rolled back. Details: "
>>> Session #49 (user: WSO2CARBON) on thread pool-54-thread-1 is waiting to
>>> lock PUBLIC.DM_ENROLMENT_OP_MAPPING while locking PUBLIC.DM_OPERATION
>>> (exclusive), PUBLIC.DM_COMMAND_OPERATION (exclusive).
>>> Session #59 (user: WSO2CARBON) on thread http-nio-9443-exec-27 is
>>> waiting to lock PUBLIC.DM_OPERATION while locking
>>> PUBLIC.DM_ENROLMENT_OP_MAPPING (exclusive), 
>>> PUBLIC.DM_DEVICE_OPERATION_RESPONSE
>>> (exclusive)."; SQL statement:
>>> INSERT INTO DM_DEVICE_OPERATION_RESPONSE(OPERATION_ID, ENROLMENT_ID,
>>> EN_OP_MAP_ID, OPERATION_RESPONSE, RECEIVED_TIMESTAMP) VALUES(?, ?, ?, ?, ?)
>>> [40001-175]
>>> at org.h2.message.DbException.getJdbcSQLException(DbException.java:332)
>>> at org.h2.message.DbException.get(DbException.java:172)
>>> at org.h2.message.DbException.get(DbException.java:149)
>>> at org.h2.table.RegularTable.doLock(RegularTable.java:504)
>>> at org.h2.table.RegularTable.lock(RegularTable.java:450)
>>> at org.h2.constraint.ConstraintReferential.existsRow(Constraint
>>> Referential.java:375)
>>> at org.h2.constraint.ConstraintReferential.checkRowOwnTable(Con
>>> straintReferential.java:367)
>>> at org.h2.constraint.ConstraintReferential.checkRow(ConstraintR
>>> eferential.java:310)
>>> at org.h2.table.Table.fireConstraints(Table.java:894)
>>> at org.h2.table.Table.fireAfterRow(Table.java:911)
>>> at org.h2.command.dml.Insert.insertRows(Insert.java:162)
>>> at org.h2.command.dml.Insert.update(Insert.java:115)
>>> at org.h2.command.CommandContainer.update(CommandContainer.java:79)
>>> at org.h2.command.Command.executeUpdate(Command.java:253)
>>> at org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(Jdbc
>>> PreparedStatement.java:154)
>>> at org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPrepared
>>> Statement.java:140)
>>> at org.wso2.carbon.device.mgt.core.operation.mgt.dao.impl.Gener
>>> icOperationDAOImpl.addOperationResponse(GenericOperationDAOI
>>> mpl.java:211)
>>> ... 59 more
>>>
>>>
>>> Thanks & regards,
>>> /charithag
>>> --
>>> *Charitha Goonetilleke*
>>> Senior Software Engineer
>>> WSO2 Inc.; http://wso2.com
>>> lean.enterprise.middleware
>>>
>>> mobile: +94 77 751 3669 <%2B94777513669>
>>> Twitter:@CharithaWs <https://twitter.com/CharithaWs>, fb: charithag
>>> <https://www.facebook.com/charithag>, linkedin: charithag
>>> <http://www.linkedin.com/in/charithag>
>>>
>>> <http://wso2.com/signature>
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "WSO2 IoT Team Group" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to iot-group+unsubscr...@wso2.com.
>>> For more options, visit https://groups.google.com/a/wso2.com/d/optout.
>>>
>>
>>
>>
>> --
>> With Regards,
>>
>> *Rasika Perera*
>> Senior Software Engineer
>> LinkedIn: http://lk.linkedin.com/in/rasika90
>>
>> <http://wso2.com/signature>
>>
>> WSO2 Inc. www.wso2.com
>> lean.enterprise.middleware
>>
>
>
>
> --
> *Charitha Goonetilleke*
> Senior Software Engineer
> WSO2 Inc.; http://wso2.com
> lean.enterprise.middleware
>
> mobile: +94 77 751 3669 <%2B94777513669>
> Twitter:@CharithaWs <https://twitter.com/CharithaWs>, fb: charithag
> <https://www.facebook.com/charithag>, linkedin: charithag
> <http://www.linkedin.com/in/charithag>
>
> <http://wso2.com/signature>
>



-- 
*Charitha Goonetilleke*
Senior Software Engineer
WSO2 Inc.; http://wso2.com
lean.enterprise.middleware

mobile: +94 77 751 3669 <%2B94777513669>
Twitter:@CharithaWs <https://twitter.com/CharithaWs>, fb: charithag
<https://www.facebook.com/charithag>, linkedin: charithag
<http://www.linkedin.com/in/charithag>

<http://wso2.com/signature>
_______________________________________________
Dev mailing list
Dev@wso2.org
http://wso2.org/cgi-bin/mailman/listinfo/dev

Reply via email to