Poslao: 23 Mar 2006 00:31
|
offline
- snoop
- Genghis Khan
- Pridružio: 18 Apr 2003
- Poruke: 8134
- Gde živiš: U kesici gumenih bombona...
|
Radim za kolegu jednog robota (ASP.NET) koji treba da cita linkove sa stranica koje procita iz Access baze i da ih upise u tabelu posebno kreiranu za te linkove.
Sve to savrseno radi, ali.
Testirao sam aplikaciju sa dva linka (mozda ukupno ima oko 30ak linkova) i sve je dodao kako treba. Dodao sam jos dva linka i tu se zaglupio tj. prijavio gresku Too many client tastks.
Znam zasto je to prijavio, to nije problem.
Naravno, zatvaram konekciju posle svakog prelaska kroz petlju i ponovo je otvaram da izvrsim upit.
Nacin na koji sam to uradio i nije nesto najsjajniji - priznajem:
petlja koja ide kroz sve zapise u tabeli linkova, f-ja koja odvaja linkove sa stranica upisuje linkove prvo u dinamicki niz, a potom for petljom za svaki clan niza upisujem u bazu. To sludi Access i pukne.
Mislio sam da generisem INSERT INTO upite za svali link i da onda odjednom izvrsim, ali ne znam da li ce i to uroditi plodom.
Probao sam da zaustavim (Sleep) dodavanje na 4 sec, ali em sto jos sporije radi, em sto nista ne pomaze .
Da li neko ima neku ideju?
Promena baze nije resenje, a i neku jacu bazu bi gomila stranica sa gomilom linkova sigurno nekada zagusilo .
Jedino da radim polako. Uradim jedan link pa se odmori, pa drugi pa se odmori pa treci i tako redom i onda se otelis dok on ne predje sve linkove (oko 500 za sada).
|
|
|
Registruj se da bi učestvovao u diskusiji. Registrovanim korisnicima se NE prikazuju reklame unutar poruka.
|
|
Poslao: 23 Mar 2006 03:24
|
offline
- beli0135
- Executor
- Pridružio: 03 Jan 2005
- Poruke: 2990
- Gde živiš: Beograd
|
Ne ide to tako sinko...
Prvo, zasto bi koristio dinamicki niz? Jel imas tabelu? To ti je dosta.
Problem je konekcija na bazu. To je ubitacno sporo, pogotovu kod access-a, a bome, i kod svih ostalih.
Kako se to radi... (predpostavka da si otvorio konekciju na bazu).
Kreiras 2 queryija. Prvi ti sluzi za citanje iz tabele linkova i tu obrces loop.
(while not query1.EoF do ... a bome, nemoj da zaboravis query1.next inace prsne dok si reko keks)
Prvo da objasnim nesto. Sve osim INSERT INTO je dobro da se izvrsava odjednom. Na zalost, gomila inserta moze ozbiljno da zezne bazu.
Znaci, ti ces u svakom prolasku kroz loop querija 1, da ocistis SQL querija2, generises insert komandu, ubacis je i izvrsis. (ExecSQL), i takodje nemoj da dodajes sa query.sql.add() nego sa query.sql.text:=
Kada je sve gotovo, zatvaras query1.
query.open je jako spora operacija i treba je izvrsavati sto manje puta.
Druga stvar... Sve je neuporedivo brzze ako imas transakcije (nisam radio sa access-om pa ne neznam).
Ono, start transaction, obavis, commit
|
|
|
|
Poslao: 23 Mar 2006 16:34
|
offline
- snoop
- Genghis Khan
- Pridružio: 18 Apr 2003
- Poruke: 8134
- Gde živiš: U kesici gumenih bombona...
|
@ Beli
Hvala na savetima...
Radio sam sa dinamickim nizovima zato da bih sve linkove stavio u njih, a posle ubacivao u bazu. Mogao sam drugacije to da uradim.
Da. I koristio sam dve konekcije i petlje.
Jedna petlja citala linkove, a druga dodavala u bazu.
Ono sto je zanimljivo, gledao sam klasu za konekcije i primetio sam neke male propuste.
Sada sve radi kako treba. Ja jesam zatvarao konekciju kako treba, ali je klasa nije zatvarala.
Tesitrao sam aplikaciju, i bez problema je ubacila u bazu ~2600 linkova.
Trebalo joj je oko 30-ak sekundi, ali je zavrsila posao.
Nisam znao da istovremeno izvrsavanje INSERT INTO upita moze da zagusi bazu. Mislio sam da mozda to nije pametno, ali nisam znao.
Vazno je da sam uvideo propust. Znaci sada sve radi.
Da se drugi ne bi mucili stim, evo klase koju sam ja koristio.
Napomena: Klasa moze da se koristi za bilo koju bazu, samo treba promeniti connection string.
using System;
using System.Data.Odbc;
using System.Configuration;
using System.Web;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace Robots
{
public class AccessConn
{
public OdbcConnection con;
public OdbcCommand cmd;
public OdbcDataReader dr;
// private bool connError; // Ako smo SP prosledili npr '=' pa da ne bi izasao iz programa, implementiramo ovu promenljivu za property
private bool connBool = false; // da li je otvorena konekcija ka bazi
private bool connRead = false; // da li je otvoren data reader
string aConn;
~AccessConn()
{
CloseConn();
}
public void OpenConn(string sql)
{
aConn = @"Driver={Microsoft Access Driver (*.mdb)};Dbq=putanja_baze;pwd=;uid=;";
try
{
con = new OdbcConnection(aConn);
con.Open();
connBool = true;
if (connBool)
{
ZatvoriRead(); // u slucaju da je reader vec otvoren zatvara ga
cmd = new OdbcCommand(sql, con);
dr = cmd.ExecuteReader();
}
}
catch (Exception ex)
{
// ConnError = true; // ako je true, onda se desila neka greska, moguce da je u pitanju sql injection
CloseConn();
}
}
private void ZatvoriRead()
{
try
{
if (connRead)
{
dr.Close();
connRead = false;
}
}
catch (Exception ex)
{
}
}
public void CloseConn()
{
try
{
ZatvoriRead();
if (connBool)
{
con.Dispose();
con.Close();
connBool = false;
}
}
catch (Exception ex)
{
}
}
}
}
|
|
|
|