Blog
Small data: workflow, long transactions and DB2
With all the big-data postings, now something about traditional SQL, running at DB2 9. We had created a web-application, that was basically a view for a database. The application displayed content of a database after the user would enter search parameters, or everything when no parameter was entered. The database contained a few hundred-thousands records. All in all very simple. The software worked fine at our test-environment. But when we deployed the software into production, it would hardly ever display data. In the logs we found frequent locking errors as follow: 15:23 ERROR (org.hibernate.engine.jdbc.spi.SqlExceptionHelper) - DB2 SQL Error: SQLCODE=-911, SQLSTATE=40001, SQLERRMC=68, DRIVER=4.1 Searching the web revealed what that error meant: a deadlock or timeout has occurred. We knew the same database was also accessed by another application, Activiti running processes written in BPMN. The processes in the Activiti-engine only inserted a few records per minute, so we didn't expect that application having a big influence. Yet how can a few inserts per minute have such a big impact? After some talking to a DBA'er and doing our own experimentation we found out about the problem, which will describe here.
As said the other application was an Activiti that executed processes (to be exact: process-definitions in BPMN). At several steps in the process, Java code was executed by the Activiti's delegate mechanism. That java code would insert data into our database.
Time | Process a(ctiviti) | Process c(onsole) | |
---|---|---|---|
1 | INSERT something INTO mytable | Process a is good to go | |
2 | SELECT * FROM mytable | Process c has to wait for process a | |
3 | INSERT something INTO myothertable | Process c still has to wait | |
4 | commit | Process a commits, finally process c can continue | |
5 | commit | Process c is now also finished |
EntityManagerFactoryImpl entityManagerFactory = (EntityManagerFactoryImpl) Persistence. createEntityManagerFactory(properties.getProperty("myunitname"); sessionFactory = entityManagerFactory.getSessionFactory(); Session session = sessionFactory.openSession(); session.getTransaction().begin(); ... session.getTransaction().commit(); session.close();Note: if you use Spring-transactions, Spring will do the above boilerplate for you. Now locks were held for a much shorter time. After this change, our console behaved normally.

Gerard van de Glind
Contact