[QFJ-119] No JDBC transactions around storing messages and updating sequence number. Created: 28/Dec/06 Updated: 20/Dec/11 Resolved: 09/Jan/07 Status: Project: Component/s: Affects Version/s: Fix Version/s: Closed QuickFIX/J Engine None Type: Reporter: Resolution: Labels: Other Paul Haefele Fixed None None Priority: Assignee: Votes: Default Steve Bate 0 Description I am curious as to the fact that their is no enclosing transaction around the storing of the messages to the database and the updating of the sequence numbers that happens in Session.sendRaw(). In here, QuickFixJ (if configured for JDBC) updates the database after it has send out the message using: state.set(msgSeqNum, messageString); state.incrNextSenderMsgSeqNum(); Both of these update the database, however they don't do it in a single transaction. Doesn't this mean the DB would be in an inconsistent state if the server where to go down between the above two statements. Indeed I was hoping to be able to hook into this transaction myself to update my own tables so as to ensure that my OMS is always inline with what QuickFix believes it has sent. I am a relative newbie to QuickFixJ, so please let me know if I am missing the boat entirely. Many thanks Paul Comments Comment by Paul Haefele [ 28/Dec/06 ] I am curious as to the fact that their is no enclosing transaction around the storing of the messages to the database and the updating of the sequence numbers that happens in Session.sendRaw(). In here, QuickFixJ (if configured for JDBC) updates the database after it has send out the message using: state.set(msgSeqNum, messageString); state.incrNextSenderMsgSeqNum(); Both of these update the database, however they don't do it in a single transaction. Doesn't this mean the DB would be in an inconsistent state if the server where to go down between the above two statements. Indeed I was hoping to be able to hook into this transaction myself to update my own tables so as to ensure that my OMS is always inline with what QuickFix believes it has sent. I am a relative newbie to QuickFixJ, so please let me know if I am missing the boat entirely. Many thanks Paul Comment by Paul Haefele [ 28/Dec/06 ] Sorry for the duplicate message above - meant to send an additional comment (below) but ended up re-pasting original... Looking further at Session.sendRaw() I see that it is doing two things: a) sending message on network (Session.send() and then b) logging this message to the database (state.set()) However I'm wondering about the failure semantics here of what would happen if our FixServer went down between (a) and (b). This could mean that the receiving Fix engine could get a message that we don't know about when restart. Wouldn't this lead us to sending a different message with the an already sent MessageID on a restart. I would have expected that (a) and (b) would have been reversed. Many thanks, Paul Comment by Steve Bate [ 09/Jan/07 ] Hi Paul, Quickfix and Quickfix/J have no transactional guarantees. This would be an interesting extension. Remember, that most of the messages stores and logs are not themselves transactional. However, the interfaces could be extended to support the potential for this behavior even if it's a no-op for most implementations. If the rare event (hopefully!) that a server crash happens between the two calls you mention, it may require some manual intervention to patch up sequence numbers or resend messages. I think if the calls are reversed it possibly lead to a dropped message, depending on exactly where the crash occurs. However, I'll look into it further. Comment by Paul Haefele [ 10/Jan/07 ] Hi Steve, Thanks for this reply. In our use of quickfixj, we want to expose the underlying transaction that jdbc will be using. This is so our own DB update can be transactionally guaranteed to occur when quickfix has transactionally committed (i.e. written to its internal store.) I've looked at Session, SessionState and MessageStore (and its implementers) and think I can expose any underlying transaction (assuming there is one) to the Application in a clean and minimal manner. Indeed I've already implemented this, but want to review (and test) it further. I'm happy to email you the code, and if you feel it will be useful and is implemented correctly, to have this committed to the quickfixj code base. In terms of the ordering, my sense is that mina is not a guaranteed delivery mechanism, and that FIX itself guarantees this via its message sequence numbers. As such a dropped message is no big issue. If we write to the store and then crash (without sending the message), when we come back up and send another message, the counterparty will simply ask for the missed message which we've stored. In the case where we send the message first (and let us say it arrives) and then crash before saving to our own store, the next message we send would have the same sequence number, but indeed be a different message. We would not know what message was send prior to the crash. Thus updating our own internal store before sending any message is I believe the preferable way to go. In any event, thanks for the reply, and most impressed with the way QuickFixJ works - great stuff. I've been working with a commercial OMS that exposes Fix messages, and the quickfixJ implementation is far more consistent and clean. Thanks again, Paul Comment by shaun barker [ 20/Dec/11 ] Hi I realise that this is closed, but we recently came upon the same problem, came to the same conclusions and also have the code available. If you want I am happy to ping up the changes? let me know if so. Otherwise - thanks for the great product! Generated at Tue Feb 09 19:03:49 CET 2016 using JIRA 7.0.10#70120sha1:37e3d7a6fc4d580639533e7f7c232c925e554a6a.