Deadlock detected

2
While debugging locally I got the stacktrace below. The curious part is that this object is a counter object with nothing special. There is no locking mechanisme in the model. I was wondering what could be causing this? Regards, Ronald [EDIT] I found the problem. Before a distance webservice call the user needed to select a origan and destination by setting a reference. When the webservice returned an error for some reason I can not comprehend at the moment the origin point reference would be set to empty and thus triggering the on change microflow and the webservice would be triggered again causing the deadlock. I have on the webservice custom error handling to log the webservice error, but there the references are not touched, so that is the mystery part for me. Since I can workaround the webservice triggering twice I am not going to delve deeper why a webservice fault causes the current not saved object loosing its reference. An error has occurred while handling the request. [User 'man1' with session id '507d60de-6d1b-4115-abb1-6a2201126253' and roles 'Medewerker, Manager'] -------- com.mendix.modules.microflowengine.MicroflowException: com.mendix.core.CoreRuntimeException: com.mendix.systemwideinterfaces.MendixRuntimeException: com.mendix.systemwideinterfaces.connectionbus.ConnectionBusException: Exception occurred while updating data. (SQL State: 40P01, Error Code: 0) at Declaratie.OCh_PersoonlijkeAdres_Van (Commit : 'Commit 'DeclaratieRegel' ') Advanced stacktrace: at com.mendix.modules.microflowengine.MicroflowUtil.processException(MicroflowUtil.java:143) Caused by: com.mendix.core.CoreRuntimeException: com.mendix.core.CoreRuntimeException: com.mendix.systemwideinterfaces.MendixRuntimeException: com.mendix.systemwideinterfaces.connectionbus.ConnectionBusException: Exception occurred while updating data. (SQL State: 40P01, Error Code: 0) at com.mendix.core.actionmanagement.ActionManager.executeInTransactionSync(ActionManager.java:163) Caused by: com.mendix.core.CoreRuntimeException: com.mendix.systemwideinterfaces.MendixRuntimeException: com.mendix.systemwideinterfaces.connectionbus.ConnectionBusException: Exception occurred while updating data. (SQL State: 40P01, Error Code: 0) at com.mendix.core.actionmanagement.ActionManager.executeSync(ActionManager.java:198) Caused by: com.mendix.systemwideinterfaces.MendixRuntimeException: com.mendix.systemwideinterfaces.connectionbus.ConnectionBusException: Exception occurred while updating data. (SQL State: 40P01, Error Code: 0) at com.mendix.util.classloading.Runner.doRunUsingClassLoaderOf(Runner.java:36) Caused by: com.mendix.systemwideinterfaces.connectionbus.ConnectionBusException: Exception occurred while updating data. (SQL State: 40P01, Error Code: 0) at com.mendix.connectionbus.connections.jdbc.JDBCDataStore.getCorrectException(JDBCDataStore.java:1453) Caused by: org.postgresql.util.PSQLException: ERROR: deadlock detected Detail: Process 2856 waits for ShareLock on transaction 301640; blocked by process 10296. Process 10296 waits for ShareLock on transaction 301636; blocked by process 2856. Hint: See server log for query details. at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2270) at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1998) at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255) at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:570) at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:420) at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:366) at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:98) at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:98) at com.mendix.connectionbus.connections.jdbc.JDBCDataStore.execUpdateQueries(JDBCDataStore.java:830) at com.mendix.connectionbus.connections.jdbc.JDBCDataStore.execUpdateQueries(JDBCDataStore.java:785) at com.mendix.connectionbus.connections.jdbc.JDBCDataStore.store(JDBCDataStore.java:555) at com.mendix.connectionbus.store.EntityStorer.storeDataSetInstance(EntityStorer.java:281) at com.mendix.connectionbus.store.EntityStorer.handleUpdateRequest(EntityStorer.java:243) at com.mendix.connectionbus.store.EntityStorer.handleRequest(EntityStorer.java:168) at com.mendix.connectionbus.store.EntityStorer.store(EntityStorer.java:79) at com.mendix.connectionbus.RequestAnalyzer.doRequest(RequestAnalyzer.java:94) at com.mendix.connectionbus.ConnectionBusImpl.doRequest(ConnectionBusImpl.java:406) at com.mendix.core.action.user.CommitAction.commit(CommitAction.scala:59) at com.mendix.core.action.user.CommitAction.commitPersistableObjects(CommitAction.scala:48) at com.mendix.core.action.user.CommitAction.executeAction(CommitAction.scala:36) at com.mendix.core.action.user.CommitAction.executeAction(CommitAction.scala:21) at com.mendix.systemwideinterfaces.core.UserAction.execute(UserAction.java:49) at com.mendix.core.actionmanagement.CoreAction.doCall(CoreAction.java:260) at com.mendix.core.actionmanagement.CoreAction.call(CoreAction.java:248) at com.mendix.core.actionmanagement.ActionManager$1.execute(ActionManager.java:188) at com.mendix.util.classloading.Runner.doRunUsingClassLoaderOf(Runner.java:32) at com.mendix.core.actionmanagement.ActionManager.executeSync(ActionManager.java:194) at com.mendix.core.actionmanagement.ActionManager.executeInTransactionSync(ActionManager.java:156) at com.mendix.core.component.InternalCore.commitWithoutEvents(InternalCore.java:217) at com.mendix.core.component.InternalCore.commitWithoutEvents(InternalCore.java:205) at com.mendix.modules.microflowengine.actions.mxobject.CommitAction.execute(CommitAction.scala:36) at com.mendix.modules.microflowengine.actions.mxobject.CommitAction.execute(CommitAction.scala:19) at com.mendix.modules.microflowengine.microflow.impl.MicroflowObject.execute(MicroflowObject.java:47) at com.mendix.modules.microflowengine.microflow.impl.MicroflowImpl.executeAfterBreakingIfNecessary(MicroflowImpl.java:192) at com.mendix.modules.microflowengine.microflow.impl.MicroflowImpl.executeAction(MicroflowImpl.java:149) at com.mendix.systemwideinterfaces.core.UserAction.execute(UserAction.java:49) at com.mendix.core.actionmanagement.CoreAction.doCall(CoreAction.java:260) at com.mendix.core.actionmanagement.CoreAction.call(CoreAction.java:248) at com.mendix.core.actionmanagement.ActionManager$1.execute(ActionManager.java:188) at com.mendix.util.classloading.Runner.doRunUsingClassLoaderOf(Runner.java:32) at com.mendix.core.actionmanagement.ActionManager.executeSync(ActionManager.java:194) at com.mendix.core.component.InternalCore.execute(InternalCore.java:386) at com.mendix.webui.actions.client.ExecuteAction.execute(ExecuteAction.java:135) at com.mendix.webui.requesthandling.ClientRequestHandler$$anonfun$handleRequest$1.apply$mcV$sp(ClientRequestHandler.scala:322) at com.mendix.webui.requesthandling.ClientRequestHandler$$anonfun$handleRequest$1.apply(ClientRequestHandler.scala:315) at com.mendix.webui.requesthandling.ClientRequestHandler$$anonfun$handleRequest$1.apply(ClientRequestHandler.scala:315) at com.mendix.core.session.Worker$$anonfun$receive$3$$anonfun$2$$anon$1.execute(ActionDispatching.scala:145) at com.mendix.util.classloading.Runner.doRunUsingClassLoaderOf(Runner.java:32) at com.mendix.core.session.Worker$$anonfun$receive$3$$anonfun$2.apply(ActionDispatching.scala:147) at scala.util.Try$.apply(Try.scala:191) at com.mendix.core.session.Worker$$anonfun$receive$3.applyOrElse(ActionDispatching.scala:141) at akka.actor.Actor$class.aroundReceive(Actor.scala:465) at com.mendix.core.session.Worker.aroundReceive(ActionDispatching.scala:137) at akka.actor.ActorCell.receiveMessage(ActorCell.scala:516) at akka.actor.ActorCell.invoke(ActorCell.scala:487) at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:238) at akka.dispatch.Mailbox.run(Mailbox.scala:220) at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:393) at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
asked
2 answers
5

What else is happening in the microflows on your page? Are there any other actions triggering around the same time? Are you pressing a mircoflow button to save the record while the OC microflow is running?


Most of the time when I see this happening it's two microflows trying to interact with the same objects, but unable continue because they are waiting on each other.

So microflow 1 first changes and commits Entity1, does stuff and commits Entity2. While microflow 2 first commits Entity2, does stuff and tries to Commit Entity1. Both microflows start around the same time, and both doe the first commit, but have to wait with the second commit until the other microflow is complete.
As a best practice you should always identify the 'Ideal commit order', and always commit your entities in that exact sequence. That is the best way to prevent this problem.
If both microflows would Commit Entity1 first, and Entity2 next, the second microflow would simply wait until the first has finished.

I would recommend enabling the DEBUG messages for LogNode microflowengine. With those messages you can see which microflows start, but take a long time to complete. If you get this message you should also see 1 other microflow complete fairly soon after the error message. That microflow would have started a longer time before that completion.
Keep in mind when looking at the platform log messages, after it says it is complete it still needs a few milliseconds to close all (db) transactions.

You can conclude that one of the entities that causes your problem is: 'DeclaratieRegel' you must have at least one other commit in that microflow (or before/after commit event). That entity is likely the other part of the problem.
If you have identified the two entities, just try and find any other microflow that commits the exact same entities and make sure that the commit is always in the exact same sequence.

answered
0

If it is a counter object, might it be reasonable to assume that the records of this entity can be accessed by multiple users/system processes at once?

If so, that might be what is causing the error, since it is a deadlock error in the DB, and not on the application level.

In the past, I've seen this kind of errors with stock entities and also counter entities, which could be accessed at the same time by multiple users. If the DB updates the record in one process other processes are not allowed to access that record.

You could either use a mechanism where the counter object is accessed in a singleton design pattern or queue the updates somehow, so that user processes aren't blocked by the counter update action.

answered