SqlCommand.Cancel and Transactions



I have a Data Access Layer that clients use to interact with the
database. The layer takes in a SqlConnection and optionally a
SqlTransaction. Clients are responsible for the upkeep of the
connection/transaction.

The layer allows clients to limit the # of records (maxsize)
returned. Suppose we keep a table of Books containing 20000 book
records.

The implementation runs the query and processes the records until
there are no more records to process OR the maxsize is reached. We
close our SqlDataReader and return the results. I realize we can use
TOP in the actual sql itself to restrict the # of records but that has
performance and query complexity issues.

One drawback about calling SqlDataReader.Close is it tries to process
the remaining records even tho I'm done with the query and the results
(see the remarks section of:
http://msdn2.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.close.aspx).

So I call Cancel on the SqlCommand object before closing it out.
However, things start breaking if I try to reuse the Transaction. The
frustrating part is that it works fine most of the time. I can
continue using the transaction after Cancel/Close as if nothing's
happened. However I'd occasionally get the following exception:
System.Data.SqlClient.SqlException: Operation cancelled by user.

This happens on an irregular basis. It works the majority of the
time. It's almost as if there's a timebomb tied to the Transaction
after the Cancel method of a related SqlCommand is called.


The following code is a distilled example of the problem (.Net
Framework 1.1, SQL Server 2000):

using System;
using System.Data;
using System.Data.SqlClient;

public class CancelTest
{
public static void Main(string[] args)
{
int maxsize = 10;
int runcount = 0;

using(SqlConnection conn = new SqlConnection("Data
Source=dvdb01a;Integrated Security=SSPI;Initial
Catalog=OperationsL1;Connect Timeout=2"))
{
conn.Open();
/// Run the main "meat" of the example 1000 times.
Eventually, we'll get...
/// System.Data.SqlClient.SqlException: Operation
cancelled by user.
for(int i=0; i<1000; i++)
{
/// The following works most of the time. But
eventually, we'll get the SqlException.
SqlTransaction trans = conn.BeginTransaction();
SqlCommand cmd = new SqlCommand("Select * from
Books",conn,trans);
SqlDataReader reader = cmd.ExecuteReader();

int recordcount = 0;
while(reader.Read() && (recordcount < maxsize))
{
Console.Write("{0}\r",++recordcount);
}
Console.WriteLine("Select completed {0} times.", +
+runcount);
cmd.Cancel();
reader.Close();
trans.Commit();
}
}
}
}

I'm at my wit's end. Any help/insight is much appreciated.

Thanks.
JT

.



Relevant Pages

  • RE: Dhcp security
    ... One way "depending on how many clients you are servicing" would be to ... create MAC (layer 2) based reservations, ... MAC reservation). ... aforementioned would be VLAN membership rubbish. ...
    (Focus-Microsoft)
  • Re: Upsizing To SQL Server
    ... reporting layer, business logic layer, database layer and so on) - you ... about it (and don't know whether SQL server is the right answer): ... Linux / Mac clients to use Access applications that live on a Windows ...
    (comp.databases.ms-access)
  • Re: download file from within Access
    ... clients click the link in my e-mail. ... get the Open, Save, Cancel dialog like you do. ... >> Access security measures added with SP 2 maybe? ... command. ...
    (microsoft.public.access.modulesdaovba)
  • Re: CP-01
    ... | Clients HATE the exit beeping. ... I dis-like enabling cancel / abort features and don't support ... unconspicous area probably a non-entry/exit delay zone. ...
    (alt.security.alarms)
  • Re: "Globaly" declare object on Server-side.
    ... Your best approach would probably be to declare the object in global.asax as ... being accessed for update by multiple clients. ... > (webservice-Business Rules-Data Layer). ... > same Singleton object which I don't want. ...
    (microsoft.public.dotnet.general)