Announcement Announcement Module
Collapse
No announcement yet.
Problem when polling messages with jdbc message store Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problem when polling messages with jdbc message store

    Hi,

    we have encountered problems with the jdbc message store, when polling concurrently from two different queues.

    The sql statement looks like this:

    SELECT
    MESSAGE.MESSAGE_ID, MESSAGE.MESSAGE_BYTES
    from
    MESSAGE
    where
    MESSAGE.MESSAGE_ID =
    (
    SELECT min(MESSAGE_ID) from MESSAGE where CREATED_DATE = (
    SELECT min(CREATED_DATE) from MESSAGE, GROUP_TO_MESSAGE
    where MESSAGE.MESSAGE_ID = GROUP_TO_MESSAGE.MESSAGE_ID
    and GROUP_TO_MESSAGE.GROUP_KEY = ? and MESSAGE.REGION = ?
    )
    )

    and does something like: look for message ids that where created at a date that the youngest message
    in the requested queue was create. if more than one id, take the min. The intention is fifo behaviour.

    BUT: if two messages were created at the same time (e.g. by a splitter) and routed to different queues, there
    is a good chance that a poller polling on queue1 fetches a messages from queue2, because the messages
    where created at the same time.

    The "outer" where clause is missing the joining "GROUP_KEY = ?" condition.

    I think this is a bug. Even more it behaves non deterministic and depends on various timing conditions.

    Regards
    Steve

  • #2
    When using the same tables for multiple channels (I assume you mean channel, not queue), you have to set a different REGION for each so their data is partitioned.

    (notice that the query includes a REGION column). By default, the message store uses a region 'DEFAULT').

    Also, FYI, a much simpler message store (specifically for backing channels) was introduced in 2.2 (JdbcChannelMessageStore). You might want to consider switching to that (but you still need a different region for each channel).

    Comment


    • #3
      Hi!

      At a glance I don't believe you
      1. Provive, please, test-case to reproduce it
      2. Analyze, please, this SELECT again and tell how CREATED_DATE can come from another GROUP_KEY
      3. To avoid any dispute in the Spring Integration 2.2 there was intruduced JdbcChannelMessageStore for JDBC-backed queus.
      http://static.springsource.org/sprin...store-channels
      It provide only one table, has an ability ChannelMessageStoreQueryProvider to achieve better perfomance and multy-threading robustness.

      WDYT now?

      Take care,
      Artem

      Comment


      • #4
        To set a different region means to define a seperate messageStore for each QueueChannel. Is that really intended?

        And even if you do so, it is again possible to fetch from the wrong QueueChannel if the messages created at the same time.

        notice that the query include a group_key column as well, but it doesn't help if it is used only to get the timestamp!

        The documentation says nothing about "one have to set a different region ..." . There is only a hint regarding name clashes which is obvious.

        steve

        Comment


        • #5
          [QUOTE=Cleric;442329]
          1. Provive, please, test-case to reproduce it
          2. Analyze, please, this SELECT again and tell how CREATED_DATE can come from another GROUP_KEY
          3. To avoid any dispute in the Spring Integration 2.2 there was intruduced JdbcChannelMessageStore for JDBC-backed queus.
          http://static.springsource.org/sprin...store-channels
          It provide only one table, has an ability ChannelMessageStoreQueryProvider to achieve better perfomance and multy-threading robustness.
          /QUOTE]

          1. I will
          2. simply use a splitter, that produces two messages, a router and two queueing channels. will result in 2 messages created at the same time. two thread polling on two different queues, and a good chance to fetch from the wrong queue.
          3. i know about the JdbcChannelMessageStore. but the older one should not have such a bug.

          Comment


          • #6
            I still do not believe that SELECT works wrong.
            Only one doubtful point is MESSAGE_ID, when two Messages are in different groups and, of course, may be in different regions, but have the same ID.
            So, how do you generate them? By default Spring Integration uses this one:
            Code:
            UUID.randomUUID()

            Comment


            • #7
              Example showing the problem

              Here is the example that shows the flow:

              Attachment

              inbound gateway -> splitter -> router -> two queues -> service ac. -> aggregator -> out

              the router def show seq no 1 is always upper, seq no 2 is lower.
              test bean checks these constraints. if everything is fine, there should never be an exception.

              so give it a try.
              Attached Files

              Comment


              • #8
                The documentation says nothing about ...
                Sorry - my mistake - not enough coffee - you don't need a different region; the groupId is constructed from the channel name so messages within a channel are unique.

                So this part of the query (and GROUP_TO_MESSAGE.GROUP_KEY = ?) should isolate all the messages for a particular channel.

                Comment


                • #9
                  Originally posted by Cleric View Post
                  Hi!
                  2. Analyze, please, this SELECT again and tell how CREATED_DATE can come from another GROUP_KEY
                  CREATED_DATE will not com from another GROUP_KEY, but if you select the message by CREATED_DATE in the outer query, that
                  message CAN come from another group_key if it has the same create_date.

                  Comment


                  • #10
                    Sorry - not enough coffee - now I see what you are saying; you are correct.

                    Please open a JIRA issue https://jira.springsource.org/browse/INT

                    In the meantime, you should be ok with the simpler JdbcChannelMessageStore. It is much simpler and more efficient; it was specifically added for message store-backed channels.

                    Comment


                    • #11
                      Originally posted by Gary Russell View Post
                      So this part of the query (and GROUP_TO_MESSAGE.GROUP_KEY = ?) should isolate all the messages for a particular channel.
                      No it doesn't. It isolates the CREATED_DATES!

                      Comment


                      • #12
                        I see in your config messageGroupStoreReaper
                        We recently noticed several issues with reaper and aggregator:
                        https://jira.springsource.org/browse/INT-2912
                        https://jira.springsource.org/browse/INT-2899
                        So, can you observe how does it work without messageGroupStoreReaper ?

                        Comment


                        • #13
                          sorry, but i dont think the messageGroupStoreReaper is nessesary to reproduce the problem.
                          you can simply delete it, the result will be the same.

                          I haved copied the snippets from our main test project.

                          Comment


                          • #14
                            NP, I've take your code and try to investigate.
                            It's interest for me, because I didn't get similar issue for years...

                            Comment


                            • #15
                              One thing to mention, the DBMS is mysql of course. version 5.1.67 . Maybe the behavior is different with another db ...

                              Comment

                              Working...
                              X