IN een ASP.NET applicatie krijg ik de volgende foutmelding bij wat intensievere gebruik.
Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
Dus kan ik wel concluderen dat hij uit de beschikbare connections loopt?
Ik zal proberen se structuur van mijn applicatie uit te leggen.
Ik mag gebruik van MS SQL server 2000 en de SQL datacomponenten van ASP.NET - dus niet de Borland componenten.
De data access heb ik in aparte classes gemaakt in deze structuur:
Code:
type
TReisInfoClass = class
private
{ Private Declarations }
public
constructor Create;
function HaalPictos(ReisNR: Integer): SqlDataReader;
...
constructor TReisInfoClass.Create;
begin
inherited Create;
end;
function TReisInfoClass.HaalPictos(ReisNR: Integer): SqlDataReader;
var
AConnection : SqlConnection;
ACommand :SqlCommand;
AParameterProjectID :SqlParameter;
ADr:SqlDataReader;
begin
// Creëer een instantie van Connection en Command object
AConnection := SqlConnection.Create(ConfigurationSettings.AppSettings['ConnString']);
ACommand := SqlCommand.Create('Pictos', AConnection);
// Zet de SQL in de CommandText property
ACommand.CommandText:=
'/*HaalPictos*/ '+
'SELECT Pub, Hint, PictogramSrc, '+
' CASE WHEN Tekst IS NULL THEN ''n'' ELSE ''j'' END AS IsLink '+
' FROM VakantiePubs VP INNER JOIN '+
' Reizen R ON VP.VakantieID = R.VakantieID INNER JOIN '+
' (SELECT PubID, Pub, Hint, Tekst, PictogramSrc FROM Pubs '+
' WHERE PictogramSrc <> '''') P ON VP.PubID = P.PubID '+
'WHERE ReisID = @ReisID '+
'ORDER BY Positie ';
// Creëer en zet de parameter
AParameterProjectID := SqlParameter.Create('@ReisID', SqlDbType.Int, 4);
AParameterProjectID.Value := TObject(ReisNR);
ACommand.Parameters.Add(AParameterProjectID);
// Voer de Command uit en maak daardoor de DataReader aan
AConnection.Open;
ADr := ACommand.ExecuteReader(CommandBehavior.CloseConnection);
// Geef de DataReader terug
Result:= ADr;
end;
...
Op mijn WebPagina (aspx) gebruik ik deze class als volgt:
Code:
procedure TReisInfo.DoeDataBind;
var
ReisInfoDB: TReisInfoClass;
begin
try
ReisInfoDB:= TReisInfoClass.Create;
DRReisInfo:= ReisInfoDB.HaalReisInfo(FReisNR);
with DLPubs do begin
DataSource:= ReisInfoDB.HaalPubs(FReisNR);
DataKeyField:= 'PubID';
DataBind;
end; //with
....
except
on E:Exception do begin
//Trace voor het debuggen, in definitieve versie uit gezet
Trace.Warn('Foutje Reis Pagina ',E. Message);
Raise;
end;
end; //except
end;
Dus ik maak een variabel SQLDataReader aan en gebruik die later met "while SQLDataReader.Read do..." of ik koppel de teruggegeven SQLDataReader aan de DataSource van DataList, DataGrid, etc.
Volgens wat ik heb begrepen zou het aanroepen/maken van de SQLDataReader met de parameter "ExecuteReader(CommandBehavior.CloseConnection )" dat de conectie gesloten wordt op moment de SQLDataReader klaar is?
De vraag is nu waarom wordt de connecties blijkbaar niet terug gegven aan de pool?
Ik denk zelf aan drie zaken.
1. In de Data access class doe dus geen direct Close van de connection. Maar dat zou volgens mij ook tot het probleem leiden dat de SQLDataReader nog niet alles heeft gelezen voordat de connection is gesloten?
2. Had ik de connection moeten Free'en in de Data access class, dat zou volgens mij tot dezelfde probleem leiden als onder 1.
3. Moet ik de instantie van de Data access class vrij geven met free in mijn WebForm?
Heeft iemand iets dergelijks ondervonden?
Bookmarks