Issue Details (XML | Word | Printable)

Key: WF-386
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Hani Suleiman
Reporter: Sébastien Launay
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
OSWorkflow

Duplicate entry constraint with MySQLWorkflowStore

Created: 07/Apr/05 09:25 AM   Updated: 07/Apr/05 01:41 PM
Component/s: Persistence Layer
Affects Version/s: 2.7
Fix Version/s: 2.8

Environment:
Debian GNU/Linux 3.1 i386
Apache Tomcat 5.0.27
MySQL 4.1.10-Debian_1-log


 Description  « Hide
Parrallel requests on a basic workflow creates duplicate primary keys constraint errors with mysql.
The problem comes from the missing instruction "nextVal" because sequences are not implemented in mysql.
Therefore, a simple table with just one field is used in osworkflow for having atomicity.
In osworkflow manual, mysql queries for getting a new step id is :
CREATE TABLE OS_STEPIDS
(
  ID bigint NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (id)
)TYPE=InnoDB;
-------------------------------------------
INSERT INTO OS_STEPIDS (ID) values (null);
SELECT max(ID) FROM OS_STEPIDS;

And, if there are multiple concurrent calls on doAction(), it is possible that the getNextStepSequence() method of MySQLWorkflowStore return the same id.
Indeed, another insert can arrive between the insert and the select query described above.
Then the max will be the last insert id and not the one we want...

Then a solution is to used the mysql instruction LAST_INSERT_ID() like this :

INSERT INTO OS_STEPIDS (ID) values (null);
SELECT LAST_INSERT_ID();

Because, mysql certifies this is atomic on a per-connection basis :
The last ID that was generated is maintained in the server on a per-connection basis. This means the value the function returns to a given client is the most recent AUTO_INCREMENT value generated by that client. The value cannot be affected by other clients, even if they generate AUTO_INCREMENT values of their own. This behavior ensures that you can retrieve your own ID without concern for the activity of other clients, and without the need for locks or transactions.

The same problem is encountered with entry ids and the getNextEntrySequence() method of JDBCWorkflowStore.
Then, we can use the same queries with a new table :

CREATE TABLE OS_ENTRYIDS
(
  ID bigint NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (id)
)TYPE=InnoDB;
-------------------------------------------
INSERT INTO OS_ENTRYIDS (ID) values (null);
SELECT LAST_INSERT_ID();

Redefining the getNextEntrySequence() method on MySQLWorkflowStore with the same code as getNextStepSequence() methode corrects this bug.

With this solution i did not notice concurrency problems by calling initialize or doAction. I test this with a web application based on tomcat and especially cocoon.

PS : I do not use JNDI by changing getConnection() for giving a SQL Connection from my connection pool.

 All   Comments   Change History      Sort Order: Ascending order - Click to sort in descending order
There are no comments yet on this issue.