[QFJ-552] Message Stores expected to be thread safe but are not Created: 05/Aug/10 Updated: 21/Apr/17 |
|
Status: | Open |
Project: | QuickFIX/J |
Component/s: | Engine |
Affects Version/s: | 1.3.0, 1.3.1, 1.3.2, 1.3.3, 1.4.0, 1.5.0 |
Fix Version/s: | None |
Type: | Bug | Priority: | Major |
Reporter: | Carmelo Piccione | Assignee: | Unassigned |
Resolution: | Unresolved | Votes: | 0 |
Labels: | None | ||
Environment: |
Linux + JDBC + SQL Server 2005 |
Attachments: | SynchronizedMessageStore.java SynchronizedMessageStoreFactory.java | ||||||||||||
Issue Links: |
|
Description |
SessionState.java starts with the following bit of code: /**
// MessageStore implementation must be thread safe Yet, looking at the JdbcStore.java and MemoryStore.java implementations, they are in fact not thread safe as designed (may also be true for FileStore.java, but haven't checked). The memory store uses a regular java.util.HashMap for all its operations, which is clearly not thread safe. I have never actually seen this cause a problem in practice, however. The jdbc store does not synchronize its use of the jdbc connection, which can lead to race conditions inside the close() method of the jtds prepared statement, as shown in the stack trace below (specifically, the jtds close() method has a boolean to determine if its connection is already closed in which case it will not doubly close it despite any subsequent calls. This value is set once the close routine is complete but occurs after the connection object has already been assigned a null value- this allows another thread to potentially access the null connection object before the boolean guard has been set). Note that this bug occurs about once a week in a production environment (usually during startup), although its frequency is probably higher than average due to many quickfixj applications accessing the same database concurrently. Example 1: java.lang.NullPointerException Example 2: java.lang.NullPointerException |
Comments |
Comment by Carmelo Piccione [ 17/Aug/10 ] |
A simple but thread safe message store implementation. The constructor takes a MessageStore instance as input and delegates all method calls to it through an object lock. This is a work around which allows safe usage of the original QFJ message stores such as JdbcStore, FileStore, and MemoryStore. |