Preventing duplicate form submission

Discussion in 'Java' started by Oleg Konovalov, Oct 31, 2006.

  1. Hi,

    I have a Java/JavaScript GUI application where I perform a lot of long DB
    operations
    [e.g. massive SQL Insert's], which takes 5-60 secs to perform.
    Sometimes user double-clicks the button or just gets impatient and clicks
    again,
    which created duplicate forcm submission and hence duplicate records.
    So I am trying to disable the button as soon as it is clicked, and as soon
    as it's done,
    re-enable it again.

    I tried to do it in Javascript, just simple: <input... name=Save...
    onclick="enabled=true;">
    and as soon as screen refreshes, it re-enables the button automatically.
    That works in some cases, however when I need to do some other Javascript
    operation
    (e.g. validate the fields on the screen), disabling the button automatically
    stops both Javascript
    and associated form action in Java which is totally unacceptable.

    Is there any other simple solution to such problems in Java or Javascript ?
    Maybe AJAX ?

    Any help is very appreciate. Please provide a code sample or a pointer to
    the resources.

    Thank you in advance,
    Oleg.
    P.S.: It probably doesn't matter much, but that is a Cocoon2.0/XSLT app
    with Actions in Java [servlet based], using JDK1.4.2 and IE6.
    Oleg Konovalov, Oct 31, 2006
    #1
    1. Advertising

  2. Oleg Konovalov

    hiwa Guest

    Oleg Konovalov wrote:
    > .....

    Search the cljp news group with 'token pattern'.
    hiwa, Oct 31, 2006
    #2
    1. Advertising

  3. Oleg Konovalov

    Gray Matter Guest

    On Tue, 31 Oct 2006 04:31:26 GMT, "Oleg Konovalov"
    <> wrote:

    >Hi,
    >
    >I have a Java/JavaScript GUI application where I perform a lot of long DB
    >operations
    >[e.g. massive SQL Insert's], which takes 5-60 secs to perform.
    >Sometimes user double-clicks the button or just gets impatient and clicks
    >again,
    >which created duplicate forcm submission and hence duplicate records.
    >So I am trying to disable the button as soon as it is clicked, and as soon
    >as it's done,
    >re-enable it again.
    >
    >I tried to do it in Javascript, just simple: <input... name=Save...
    >onclick="enabled=true;">
    >and as soon as screen refreshes, it re-enables the button automatically.
    >That works in some cases, however when I need to do some other Javascript
    >operation
    >(e.g. validate the fields on the screen), disabling the button automatically
    >stops both Javascript
    >and associated form action in Java which is totally unacceptable.
    >
    >Is there any other simple solution to such problems in Java or Javascript ?
    >Maybe AJAX ?
    >
    >Any help is very appreciate. Please provide a code sample or a pointer to
    >the resources.
    >
    >Thank you in advance,
    >Oleg.
    >P.S.: It probably doesn't matter much, but that is a Cocoon2.0/XSLT app
    >with Actions in Java [servlet based], using JDK1.4.2 and IE6.
    >


    If you're able to submit multiple, duplicate records, the database
    most likely does not have proper constraints set up. Good software
    design practices do not rely on the GUI to prevent multiple
    submissions.
    Gray Matter, Oct 31, 2006
    #3
  4. Oleg Konovalov

    Mark Rafn Guest

    Oleg Konovalov <> wrote:
    >I have a Java/JavaScript GUI application where I perform a lot of long DB
    >operations
    >[e.g. massive SQL Insert's], which takes 5-60 secs to perform.


    Don't do these synchronously. It's just mean to users, and a bad design. You
    should use a background thread to do the inserts, and have a status page that
    auto-refreshes (or uses AJAX if you're fancy) until the operation is complete.

    >Sometimes user double-clicks the button or just gets impatient and clicks
    >again, which created duplicate forcm submission and hence duplicate records.


    Make your call idempotent. Include on the form a unique identifier (cf
    java.util.UUID) that gets submitted along with the data, and the server
    can simply ignore duplicate submissions.

    >So I am trying to disable the button as soon as it is clicked, and as soon
    >as it's done, re-enable it again.


    Good. This is a nice backup to the above. But if you do it right, you
    never need to re-enable it explicitly. The form submission disables it, and
    the results page doesn't have the button on it. When the user wants to make
    a new submission, they go to the submission page, where it's enabled because
    it's a new load of the page.

    >and as soon as screen refreshes, it re-enables the button automatically.


    So don't do that. Don't refresh the page, go to a results page instead.

    >That works in some cases, however when I need to do some other Javascript
    >operation (e.g. validate the fields on the screen), disabling the button
    >automatically stops both Javascript and associated form action in Java
    >which is totally unacceptable.


    What? I don't understand this requirement. If you're showing the user a
    form, it is because you want them to submit it. If you don't want them to
    submit it, don't show the form. Showing a form that you can validate but not
    submit is lunacy.

    >Is there any other simple solution to such problems in Java or Javascript ?
    >Maybe AJAX ?


    Design your app rationally. There's no technological pixie dust that fixes a
    bad design.
    --
    Mark Rafn <http://www.dagon.net/>
    Mark Rafn, Oct 31, 2006
    #4
  5. Gray Matter wrote:
    > On Tue, 31 Oct 2006 04:31:26 GMT, "Oleg Konovalov"
    > <> wrote:
    >> I have a Java/JavaScript GUI application where I perform a lot of long DB
    >> operations
    >> [e.g. massive SQL Insert's], which takes 5-60 secs to perform.
    >> Sometimes user double-clicks the button or just gets impatient and clicks
    >> again,
    >> which created duplicate forcm submission and hence duplicate records.
    >> So I am trying to disable the button as soon as it is clicked, and as soon
    >> as it's done,
    >> re-enable it again.


    > If you're able to submit multiple, duplicate records, the database
    > most likely does not have proper constraints set up. Good software
    > design practices do not rely on the GUI to prevent multiple
    > submissions.


    Not necesarrily.

    Maybe not even likely.

    Only INSERT where the business rules guarantee a field
    mapped to user input to be unique should fall in that
    category.

    Arne
    =?ISO-8859-1?Q?Arne_Vajh=F8j?=, Nov 1, 2006
    #5
  6. Oleg Konovalov

    Lew Guest

    Mark Rafn wrote:
    > Make your call idempotent. Include on the form a unique identifier (cf
    > java.util.UUID) that gets submitted along with the data, and the server
    > can simply ignore duplicate submissions.


    I have seen variations on the token pattern in Web forms -

    - The cited approach - a hidden field that keys the transaction. Presumably
    the key is matched to a session token that is kept until the transaction
    completes.

    - A session token that is generated on page load and removed from the session
    upon first submit; absent the token the transaction request is ignored. This
    does not require unique token values.
    session.setAttribute( "idempotency", SAME_VALUE_EVERY_TIME );

    It surprised me when I first read of this pattern that the writer espoused the
    latter variant.

    I wonder of the advantages, disadvantages and gotchas of each approach.

    IMHO:
    - The second seems slightly more elegant, and idioms of void appeal to me
    anyway. (Checking for absence, rather than checking for presence.) Checkng
    for absence is slightly simpler than checking for equality.

    - Second one has slightly less work to do, without UUIDs.

    - First one might be more extendible in the security aspect.

    /Lew
    Lew, Nov 1, 2006
    #6
  7. "Oleg Konovalov" <> writes:

    > I have a Java/JavaScript GUI application where I perform a lot of
    > long DB operations [e.g. massive SQL Insert's], which takes 5-60
    > secs to perform.


    Look into optimizing that using JDBC batches.

    As another poster suggested, return to the user immediately after
    setting up the job in a different thread. However, since you're really
    not supposed to fire off threads in app-server containers - even
    servlet containers - it would be better to deliver the "job" to a JMS
    queue and have some other app read from it and do the actual database
    work.

    Some open-source products to help you get there:

    ActiveMQ for the JMS bit:

    http://www.activemq.org/site/home.html

    Or take the plunge into using the MULE ESB container if you want to
    automate as much as possible of the work:

    http://mule.mulesource.org/wiki/display/MULE/Home
    Tor Iver Wilhelmsen, Nov 1, 2006
    #7
  8. Oleg Konovalov

    Daniel Pitts Guest

    Tor Iver Wilhelmsen wrote:
    ....
    > setting up the job in a different thread. However, since you're really
    > not supposed to fire off threads in app-server containers - even

    ....

    Really? I never heard that. It might make sense, but I'd like to read
    more about that. Can you give a citation? One of our tools does a lot
    of multitasking, but if it should be done another way, I'd like to know
    why/how.

    Thanks,
    Daniel.
    Daniel Pitts, Nov 1, 2006
    #8
  9. "Daniel Pitts" <> writes:

    > Really? I never heard that. It might make sense, but I'd like to read
    > more about that. Can you give a citation? One of our tools does a lot
    > of multitasking, but if it should be done another way, I'd like to know
    > why/how.


    I might be mistaken, I heard it sometime back in the bad old days of
    EJB 1.1 and wrestling with Websphere 3; probably from some IBM
    consultant.

    So, a modified statement: You can use thread in applications running
    in a container like Tomcat etc. *as long as they don't operate on
    objects managed by the container's lifecycle mechanisms*.
    Tor Iver Wilhelmsen, Nov 2, 2006
    #9
  10. Tor Iver Wilhelmsen wrote:
    > "Daniel Pitts" <> writes:
    >> Really? I never heard that. It might make sense, but I'd like to read
    >> more about that. Can you give a citation? One of our tools does a lot
    >> of multitasking, but if it should be done another way, I'd like to know
    >> why/how.

    >
    > I might be mistaken, I heard it sometime back in the bad old days of
    > EJB 1.1 and wrestling with Websphere 3; probably from some IBM
    > consultant.
    >
    > So, a modified statement: You can use thread in applications running
    > in a container like Tomcat etc. *as long as they don't operate on
    > objects managed by the container's lifecycle mechanisms*.


    servlet container : bad practice

    EJB container : strictly forbidden

    EJB 2.1 spec section 25.1.2:

    The enterprise bean must not attempt to manage threads. The enterprise
    bean must not attempt
    to start, stop, suspend, or resume a thread, or to change a thread’s
    priority or name. The enterprise
    bean must not attempt to manage thread groups.

    (it is in previous EJB specs as well)

    Arne
    =?windows-1252?Q?Arne_Vajh=F8j?=, Nov 2, 2006
    #10
  11. Any Javascript or Ajax solutions ?


    "hiwa" <> wrote in message
    news:...
    > Oleg Konovalov wrote:
    >> .....

    > Search the cljp news group with 'token pattern'.
    >
    >
    Oleg Konovalov, Nov 4, 2006
    #11
  12. Oleg Konovalov

    Lew Guest

    (f-u set to clj.programmer)

    Oleg Konovalov wrote:
    > Hi,
    >
    > I have a Java/JavaScript GUI application where I perform a lot of long DB
    > operations
    > [e.g. massive SQL Insert's], which takes 5-60 secs to perform.
    > Sometimes user double-clicks the button or just gets impatient and clicks
    > again,
    > which created duplicate forcm submission and hence duplicate records.
    > So I am trying to disable the button as soon as it is clicked, and as soon
    > as it's done,
    > re-enable it again.


    Trying to disable a browser control (back button, refresh) from the server is
    wrong and fraught with difficulty.

    Make your transactions idempotent and stop trying to screw up people's browsers.

    Another poster already referred you to the Token pattern. It is a solution.

    - Lew
    Lew, Dec 5, 2006
    #12
  13. Oleg Konovalov

    Jim Land Guest

    Lew <> wrote in
    news::

    > Make your transactions idempotent


    Huh? What does that mean?
    Jim Land, Dec 6, 2006
    #13
  14. Oleg Konovalov

    Stefan Ram Guest

    Jim Land <RrrrFfffTttt(NO)@(SPAM)hotmail.com> writes:
    >>Make your transactions idempotent

    >Huh? What does that mean?


    Huh? Has access to Wikipedia been restricted in your country?
    Stefan Ram, Dec 6, 2006
    #14
  15. Oleg Konovalov

    Lew Guest

    Lew <> wrote:
    >> Make your transactions idempotent


    Jim Land wrote:
    > Huh? What does that mean?


    It means no further state change occurs after the first time.

    For example, if a bank application processed deposit X once, say, adding 100
    euros to a balance of 1000. The new balance is 1100. If the same deposit, X,
    were reapplied, the balance would remain 1100, not jump again to 1200.

    http://en.wikipedia.org/wiki/Idempotence_(computer_science)

    - Lew
    Lew, Dec 6, 2006
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Boban Dragojlovic

    duplicate form submission

    Boban Dragojlovic, Feb 2, 2004, in forum: ASP .Net
    Replies:
    2
    Views:
    558
    Boban Dragojlovic
    Feb 3, 2004
  2. cool2005

    Duplicate submission prevention

    cool2005, Sep 26, 2006, in forum: Java
    Replies:
    3
    Views:
    1,934
    cool2005
    Sep 26, 2006
  3. CJM

    Preventing a 2nd form submission

    CJM, Jun 13, 2005, in forum: ASP General
    Replies:
    8
    Views:
    163
    Bob Barrows [MVP]
    Jun 14, 2005
  4. Replies:
    3
    Views:
    197
  5. Oleg Konovalov

    Preventing duplicate form submission

    Oleg Konovalov, Oct 31, 2006, in forum: Javascript
    Replies:
    8
    Views:
    180
Loading...

Share This Page