On Sat, May 18, 2002 at 12:28:04PM +0100, Steve Keay wrote: > We also use datacash and it seems to work quite well - post the CC > number, amount, etc., via https and they return "yes" or "no" with a > transaction tracking number.
A firm I used to work for (sadly "dust to dust, ashes to ashes, liquidity to liquidation") used datacash, "and it was good" (not that we every really quite got live paying customers). However, we also used perl talking to Oracle. And we had this nasty revelation: BEWARE OF TRANSACTIONS We figured that we had made a nasty race condition in our system when the punter pressed the final "pay for it" user -> http request -> our server perl -> Oracle At this point the oracle stored procedure started. Being a transactional database, the various stored procedure calls were doing things in one transaction (which I believe is that default, although I'm not sure if that is Oracle's default, or the default setting on PS/SQL programmers) The stored procedure initiated a call onwards to Datacash (using more perl) to make the credit card transaction. Oracle -> perl -> encrypted http request -> Datacash at this point, Datacash does stuff, parts the customer from their money, and initiates the return transaction. This could take several seconds: encrypted <- http response our server perl <- Oracle <- perl (commit) http <- <- response user All well and good. But, what happened in our system if the user pressed the browser stop button somewhere in the several seconds where we're waiting for Datacash? We figured the following "and were sore afraid" (briefly, but glad we rewrote things to avoid this problem): [user presses stop. browser drops TCP connection] encrypted <- http response our server perl <- Oracle <- perl attempt http <- !! response At this point the perl script tries to write its response. The user has caused the browser to close the TCP connection, so the server gets a SIGPIPE and unceremoniously kills the perl script. Because the perl script is killed, and does not exit cleanly, it drops the connection to Oracle. So Oracle rolls back cleanly. That's what Oracle is designed to do. Erk. Because what we now have the following situation: Datacash has processed our transaction completely, and has removed money from the customer. Our Oracle database has no record of this ever happening. We solved the problem (IIRC) by having a commit as we were about to initiate a chat with the Datacash server, and a second commit after we'd just completed the chat with Datacash, so that we would be able to spot any partial or late aborted financial transactions. I just thought that I should warn you, as datacash makes it easy to set things up, and you may not be aware of this subtle gotcha. Nicholas Clark -- Even better than the real thing: http://nms-cgi.sourceforge.net/