M Wells (planetthoughtful@gmail.com) writes:
[quoted text, click to view] > If the procedure doesn't fail any of the @@Error tests, the
> transaction is committed, and a membership number is SELECTed to be
> returned.
>
> SELECT '0' as error, @memnum as membershipnumber
>
> The @memnum variable is populated within the transaction.
>
> Back in the ASP page we test both for the proc returning an empty
> recordset, or for it passing an explicit value in the error field, and
> push the page to an error page if either of these conditions are met.
>
> If, on the other hand, none of these conditions are met, and the
> membershipnumber field in the recordset is populated with a valid
> membership number, we push to a confirmation page.
>
> This confirmation page receives the membership number in a session
> variable, performs a SELECT against TableB (the table that received
> the insert during the proc) using that membership number in the WHERE
> clause, and the resultant recordset is used to populate the
> confirmation details on that page. That recordset is also then used to
> populate the details of a confirmation email, which is automatically
> sent by the confirmation page.
>
> And now here's our problem: we've become aware of a handfull of people
> who have gone through the enrollment process, have received the
> confirmation email containing the information they supplied as
> expected, but the data appears to be entirely missing from our tables.
As I understand, this is an intermittent problem, and you don't have a
reproducible scenario. This make such a problem much more difficult
to track down. And if you make changes to address, you cannot really
be sure that you fixed the right thing.
One thing that is not clear to me is whether it is the same SQL Server
process that runs the stored procedure and the gets the data to the
confirmation page, or whether they are two different. (I should butt
in that I don't know ASP or IIS, so this talk about session variables
etc, tells me little.)
If it is the same SQL Server process, here is something that could
happen:
1) The stored procedure first run unsuccessfully, and a transaction
is started, but then neither committed nor rolled back.
2) The process then runs the procedure successfully, and then gets
the data to the confirmation page. This time a nested transaction
was started and committed. However, "commit" in the case of an
inner transaction just means that transaction count is decremented.
3) The process goes on and registers and confirms more enrollments.
4) Eventually the process is logged out, still with an open transaction.
All enrollments are now rolled back.
So why in step 1, would this happen? It can be a coding error in
the stored procedure, so that a rollback is not executed when it
should. But it could also be a client-side thing. Say that the
procedure is blocked for some reason, and the client gets a command
timeout. In this case the transaction started by the stored procedure
is *not* rolled back. This a really nasty gotcha.
If the confirmation page is really a separate SQL Server connection -
and you should really use the SQL Server Profiler to verify this - then
the data has been committed, and thus it has later been removed. Well,
if the confirmation reads with NOLOCK, are back to the previous
scenario.
One thing you should investigate in either case, is whether these missing
enrollments happened at different points in time, or if they are clustered.
That could give a clue of what may have happened.
I hope this has given you some more ideas of what to look for.
--
Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se
Books Online for SQL Server SP3 at