> I have a mod_perl application that takes a request from a client, then does
> some transaction processing with a remote system, which then returns a
> success/fail result to the client. The transaction MUST happen only ONCE per
> client session.
>
> PROBLEM: the client clicks the submit buttom twice thus sending two
> requests, spawning two different processes to do the same remote
> transaction. BUT, the client request MUST be processed only ONCE for a given
> session_id. The first request will start a process to initiate the remote
> transaction, and then the second request process start, not knowing about
> the first process. The result is that the client has the transaction
> performed two times!
>
> How do you handle this? My first thought is to write a "processing status"
> value to the session hash (using apache::session) AS SOON as the first
> request is received, and then when the second duplicate request is received,
> check the "processing status" in the session hash. If the processing status
> is "in progress", then wait till the processing status in the session hash
> is updated by the first request process and return the result.....
>
> Is my concept on target? Is my implementation right? (or should I write
> directly to the files system?)
>
> Does anyone have any experience with such things? Can you give me your
> wisdom?
If the form page is generated dynamically, insert a magic (unique)
number/string hidden field, when you do INSERT, insert the magic number
into a DB along with request. Before inserting the record, check whether
there is already a record with this magic. If there is do not insert,
otherwise continue.
I dunno what SQL engine implementation you use, but if it's a
multithreaded (not msql!) you can have a race problem, just like with
external file locking (not flock!), so you do the check, find nothing but
the process gets context switched and another thread inserts the same
record. Then when the control comes to your process (thread) it happily
duplicates the record, without knowing that another thread already did
that. So what you need is an automic operation (test and insert). Read
your engine's manual to find out how to do:
INSERT (something) if not SELECT (magick is already there)
Another solution is to use javascript to maintain a state (the easiest),
but user can turn it off, so you cannot rely on that.
Hope this helps...
To the Victor's note of not being able to perform double click (resubmit)
-- Netscape and IE aren't the only browsers/user agents. Use LWP,
LWP::ParallelUA or a similar module instead, to run not just 2 requests in
parallel but many of them. In fact you can act as a super-human submitting
hundreds requests in the same millisecond. Hey isn't called a benchmarking
process :")
_______________________________________________________________________
Stas Bekman mailto:[EMAIL PROTECTED] http://www.stason.org/stas
Perl,CGI,Apache,Linux,Web,Java,PC http://www.stason.org/stas/TULARC
perl.apache.org modperl.sourcegarden.org perlmonth.com perl.org
single o-> + single o-+ = singlesheaven http://www.singlesheaven.com