Když aplikace C++ Builderu používající DBE se připojuje
k databázi, pak připojení je zaobaleno komponentou TDatabase. Komponenta
databáze zaobaluje připojení k jedné databázi v kontextu sezení BDE v aplikaci.
Následující body popisují komponentu databáze a jak manipulovat s databázovým
připojením.
Komponenta databáze je také používána ke
správě transakcí v aplikacích založených na BDE. Jiné použití komponenty
databáze je aplikování odložených aktualizací na připojené tabulky. Tím
se ale zatím zabývat nebudeme.
Seznámení s
trvalými a dočasnými komponentami databáze
Každé databázové připojení v aplikaci je zaobaleno komponentou
databáze a to bez ohledu na to, zda explicitně poskytneme komponentu
databáze při návrhu nebo ji vytvoříme dynamicky za běhu. Když se aplikace
pokusí připojit k databázi, pak je použita již vytvořená trvalá komponenta
databáze nebo je generována dočasná komponenta databáze, která existuje
pouze po dobu trvání připojení.
Dočasné komponenty databáze jsou vytvářeny podle potřeby
pro všechny datové množiny v datovém modulu nebo na formuláři, když je
nevytvoříme sami. Dočasné komponenty databáze poskytují dostatečnou podporu
pro většinu typických databázových aplikací, které nevyžadují zpracování
detailů databázového připojení. Pro většinu aplikací klient/server můžeme
vytvořit svou vlastní komponentu databáze namísto použití dočasné. Získáme
tím větší možnosti řízení databáze včetně:
-
Vytváření trvalých databázových připojení.
-
Přizpůsobení přihlašování k databázovému serveru.
-
Řízení transakcí a specifikace úrovně izolace transakcí.
-
Vytváření lokálních přezdívek BDE pro naši aplikaci.
Budeme se zde zabývat ještě těmito body:
Použití dočasné komponenty
databáze
Dočasné komponenty databáze jsou automaticky generovány podle
potřeby. Např. pokud umístíme komponentu TTable na formulář, nastavíme
její vlastnosti a otevřeme tabulku bez použití a nastavení komponenty TDatabase
a přiřazení komponenty tabulky k ní, pak C++ Builder vytváří pro tabulku
dočasnou komponentu databáze.
Některé klíčové vlastnosti dočasné komponenty databáze
jsou určeny sezením ve kterém jsme. Např. řízením vlastnosti KeepConnections
sezení určujeme, zda databázové připojení je udržováno i když jeho datové
množiny jsou uzavřeny (implicitně) nebo zda připojení je zrušeno, když
všechny jeho datové množiny jsou uzavřeny. Podobně, implicitní událost
OnPassword
pro sezení zajišťuje, že když aplikace se pokusí o připojení k databázi
na serveru, která vyžaduje heslo, pak je zobrazeno standardní dialogové
okno pro zadávání hesla. Ostatní vlastnosti dočasné komponenty databáze
poskytují standardní přihlášení a zpracování transakcí.
Implicitní vlastnosti vytvořené pro dočasnou komponentu
databáze poskytují vhodné chování pro širokou řadu situací. Nicméně v některých
aplikacích typu klient/server s mnoha uživateli a různými požadavky na
databázové připojení, musíme vytvořit svou vlastní komponentu databáze.
Vytváření komponent
databáze při návrhu
Stránka Data Access Palety komponent obsahuje komponentu
databáze, kterou můžeme umístit do datového modulu nebo na formulář. Hlavní
výhodou vytváření komponenty databáze při návrhu je to, že můžeme nastavit
počáteční hodnoty vlastností a zapsat pro ní obsluhu události OnLogin.
OnLogin
nabízí možnost přizpůsobení zpracování bezpečnosti na databázovém serveru,
když se komponenta databáze poprvé připojuje k serveru.
Vytváření komponent
databáze za běhu aplikace
Komponenty databáze můžeme také vytvářet dynamicky za běhu
aplikace. Když takto vytváříme databázové komponenty, pak jim musíme dát
unikátní jméno a přiřadit je k sezení.
Komponentu vytváříme pomocí operátoru new. Následující
funkce přebírá jméno databáze a jméno sezení a vytváří komponentu databáze
za běhu, přiřazuje ji ke specifikovanému sezení (v případě potřeby vytváří
nové sezení) a nastavuje několik klíčových vlastností komponenty databáze:
TDatabase* __fastcall TForm1::RunTimeDbCreate(const
AnsiString DatabaseName,
const AnsiString SessionName)
{
// Pokud sezení existuje, pak je uděláme
aktivním, neexistuje-li,
// pak vytvoříme nové sezení
Sessions->OpenSession(SessionName);
TSession *pSession = Sessions->FindSession(SessionName);
TDatabase *TempDatabase = pSession->FindDatabase(DatabaseName);
// pokud databáze již existuje, pak
návrat
if (TempDatabase)
return TempDatabase;
// Vytvoření nové komponenty databáze
TempDatabase = new TDatabase(this);
try {
TempDatabase->DatabaseName
= DatabaseName;
TempDatabase->SessionName
= SessionName;
TempDatabase->KeepConnection
= true;
return pSession->OpenDatabase(DatabaseName);
}
catch (...) {
delete TempDatabase;
throw;
}
}
Následující část kódu ukazuje jak můžeme volat tuto funkci
k vytvoření komponenty databáze pro implicitní sezení:
TDatabase *MyDatabase[10];
// pole ukazatelů na databáze
int MyDBCount = 0;
// dřívější inicializace MyDBCount
...
// později, vytvoření komponenty databáze
MyDatabase[MyDBCount] = RunTimeDbCreate(AnsiString("MyDb")
+
IntToStr(MyDBCount++), "");
...
Řízení připojení
Když vytvoříme komponentu databáze při návrhu nebo za běhu
aplikace, pak můžeme použít vlastnosti, události a metody TDatabase
k řízení a změně jejího chování v naší aplikaci. V následujících bodech
je popsáno jak manipulovat s komponentami databáze:
Přiřazování komponenty
databáze k sezení
Všechny komponenty databáze musí být přiřazeny k BDE sezení.
Dvě vlastnosti komponenty databáze Session a SessionName
zřizují toto přiřazení.
SessionName identifikuje přezdívku sezení, ke
které je přiřazena komponenta databáze. Když poprvé vytvoříme komponentu
databáze při návrhu, pak SessionName je nastaveno na "Default".
Vícevláknové nebo reentrantní BDE aplikace mohou mít více než jedno sezení.
Během návrhu můžeme získat přípustné SessionName z rozbalovacího
seznamu v Inspektoru objektů. Jména sezení v tomto seznamu jsou získána
z vlastností SessionName všech komponent sezení v aplikaci.
Vlastnost Session je určená pouze pro čtení a
dostupná pouze za běhu aplikace a odkazuje se na komponentu sezení specifikovanou
vlastností
SessoinName. Např. pokud SessionName je prázdná
nebo "Default", pak vlastnost Session ukazuje na stejnou instanci
TSessoinjako
ukazuje globální proměnná Session. Session umožňuje aplikaci
přistupovat k vlastnostem, metodám a událostem v nadřízené komponentě sezení
komponenty databáze bez nutnosti znát aktuální jméno sezení. To je užitečné,
když komponenta databáze je přiřazována za běhu k různým sezením.
Specifikování přezdívek BDE
AliasName a DriverName jsou vzájemně vylučující
se vlastnosti.
AliasName specifikuje jméno existující přezdívky
BDE k použití pro komponentu databáze. Přezdívky jsou zobrazeny v rozbalitelných
seznamech pro komponenty datových množin a tak se můžeme spojit s konkrétní
komponentou databáze. Pokud specifikujeme
AliasName pro komponentu
databáze, pak všechny hodnoty přiřazené k DriverName jsou vyprázdněny,
protože jméno ovladače je vždy částí přezdívky BDE.
Poznámka: Přezdívky BDE vytvoříme a editujeme
pomocí Průzkumníka databáze nebo Administrátora BDE. S těmito činnostmi
jsme se již seznámili v předchozích kapitolách.
DatabaseName umožňuje poskytnutí aplikačního jména
pro komponentu databáze. Toto jméno používáme společně s AliasName
nebo DriverName a je lokální v naši aplikaci. DatabaseName
může být přezdívka BDE nebo pro soubory Paradoxu a dBASE úplná specifikace
souboru. Podobně jako
AliasName i DatabaseName se zobrazuje
v rozbalitelných seznamech v komponentách datových množin.
DriverName je jméno ovladače BDE. Jméno ovladače
je jedním parametrem v přezdívce BDE, ale můžeme specifikovat jméno ovladače
místo přezdívky, když vytváříme lokální přezdívku BDE pro komponentu databáze
pomocí vlastnosti
DatabaseName. Pokud specifikujeme DriverName,
pak všechny hodnoty již přiřazené k AliasName jsou vyprázdněny (k
zabránění možným konfliktům mezi jménem specifikovaného ovladače a jménem
ovladače, který je částí přezdívky BDE identifikované v AliasName).
Ke specifikaci přezdívky BDE při návrhu, přiřadíme ovladač
BDE nebo vytvoříme lokální přezdívku BDE dvojitým kliknutím na komponentě
databáze k vyvolání Editoru vlastností databáze. V tomto editoru můžeme
zadat DatabaseName v části Name, existující přezdívku BDE
v kombinovaném ovladači Alias Name nebo můžeme volit z existující
přezdívky v rozbalovacím seznamu. Kombinovaný ovladač Driver Name
umožňuje zadávat jméno existujícího ovladače BDE pro vlastnost DriverName
nebo můžeme volit z existujících jmen ovladačů v rozbalovacím seznamu.
Poznámka: Editor také umožňuje zobrazit a nastavit
připojovací parametry BDE a nastavit stav vlastností LoginPrompt
a KeepConnection.
K nastavení DatabaseName, AliasName nebo
DriverName
za běhu aplikace, vložíme příslušný přiřazovací příkaz do našeho kódu.
Např. následující kód použije text z editačního ovladače k určení přezdívky
pro komponentu databáze Database1:
Database1->DatabaseName = Edit1->Text;
Nastavování parametrů
přezdívek BDE
Během návrhu můžeme vytvářet nebo editovat připojovací parametry
třemi způsoby:
-
Pomocí Průzkumníka databáze nebo Administrátora BDE vytvoříme
nebo modifikujeme přezdívky BDE včetně parametrů.
-
Dvojitým kliknutím na vlastnosti Params v Inspektoru
objektů vyvoláme Editor seznamu řetězců.
-
Dvojitým kliknutím na komponentě databáze v datovém modulu
nebo na formuláři vyvoláme Editor vlastností databáze.
Všechny tyto metody editují vlastnost Params komponenty
databáze.
Params je seznam řetězců obsahující připojovací parametry
databáze pro přezdívku BDE přiřazenou ke komponentě databáze. Typické připojovací
parametry zahrnují jméno serveru, velikost paměti cache, jazykový ovladač
a dotazový režim SQL.
Když poprvé vyvoláme Editor vlastností databáze, pak
parametry pro přezdívku BDE nejsou viditelné. K zobrazení současného nastavení
stiskneme
Defaults. Současné parametry jsou zobrazeny v části Parameter
overrides. Existující položky můžeme editovat nebo přidávat nové. Pro
smazání existujících parametrů stiskneme Clear. Změny se projeví
až po stisku
OK.
Za běhu aplikace může nastavovat parametry přezdívky
pouze přímou editací vlastnosti Params.
Řízení přihlašování
ke vzdálenému serveru
Většina vzdálených databázových serverů obsahuje bezpečnostní
služby k zamezení neautorizovaného přístupu. Obecně server vyžaduje jméno
uživatele a heslo před umožněním přístupu k databázi. Jestliže se potřebujeme
přihlásit k serveru během návrhu, pak je zobrazeno standardní okno přihlašování
pro zadání jména a hesla uživatele.
Jsou tři způsoby jak provést přihlášení za běhu aplikace:
-
Nastavíme vlastnost LoginPrompt komponenty databáze
na true (implicitně). Aplikace bude zobrazovat standardní dialogové
okno přihlašování pro zadání jména a hesla uživatele.
-
Nastavíme LoginPrompt na false a vložíme parametry
USER NAME a PASSWORD do vlastnosti Params pro komponentu databáze.
Např.
USER NAME=SYSDBA
PASSWORD=masterkey
Upozornění: Jelikož vlastnost Params
je snadno zobrazitelná, není tato metoda doporučována.
-
Zapíšeme obsluhu události OnLogin pro komponentu databáze
a použijeme ji pro nastavení přihlašovacích parametrů za běhu. OnLogin
získá kopii vlastnosti Params komponenty databáze, kterou můžeme
modifikovat. Jméno této kopie v OnLogin je LoginParams. Vlastnost
Values
použijeme k nastavení nebo změně přihlašovacích parametrů takto:
LoginParams->Values["USER NAME"] = UserName;
LoginParams->Values["PASSWORD"] = PasswordSearch(UserName);
Při ukončení OnLogin jsou LoginParams předány
zpět do
Params a jsou použity k navázání připojení.
Připojení k databázovému
serveru
Jsou dva způsoby připojení k databázovému serveru pomocí
komponenty databáze:
-
Volání metody Open.
-
Nastavením vlastnosti Connected na true.
Nastavením Connected na true vyvoláme metodu
Open.
Open
ověřuje zda databáze specifikovaná vlastnostmi
DatabaseName nebo
Directory
existuje a pokud existuje obsluha události OnLogin pro komponentu
databáze, pak je provedena. Jinak je zobrazeno standardní dialogové okno
přihlašování.
Poznámka: Když komponenta databáze není připojena
k serveru a aplikace se pokusí otevřít datovou množinu přiřazenou ke komponentě
databáze, pak nejprve je volána metoda Open komponenty databáze
k zřízení připojení. Pokud datová množina není přiřazena k existující komponentě
databáze, pak je vytvořena dočasná komponenta databáze a je použita pro
zřízení připojení.
Po zřízení databázového připojení je toto připojení dále
udržováno pokud je aktivní alespoň jedna datová množina. Když již není
aktivní žádná datová množina, pak osud připojení je určen vlastností KeepConnection
komponenty databáze.
Speciální úvahy
při připojování ke vzdálenému serveru
Když se připojíme ke vzdálenému databázovému serveru z aplikace,
pak aplikace použije BDE nebo ovladač SQL Links ke zřízení připojení.
BDE může komunikovat s podporovanými ovladači ODBC. Ovladače SQL Links
a ODBC musí být před zřízením připojení správně nakonfigurovány. Konfigurační
parametry jsou uloženy ve vlastnosti Params komponenty databáze.
Jako část konfigurace může být nutno specifikovat síťový
protokol používaný serverem, jako je SPX/IPX nebo TCP/IP a jeho parametry.
V mnoha případech, konfigurace síťového protokolu je obsloužena nastavovacím
softwarem klienta. Pro ODBC může být také nutné provést nastavení ovladače
pomocí Správce ovladačů ODBC.
Zřízení a inicializace připojení mezi klientem a serverem
může být problematické. Následující seznam nám může pomoci při odstraňování
problémů:
-
Je naše klientská strana připojení správně konfigurována?
-
Pokud používáme TCP/IP:
-
Je náš komunikační software TCP/IP instalován. Je správně
instalován WINSOCK.DLL?
-
Je IP adresa serveru registrována v souboru HOSTS klienta?
-
Je DNS správně konfigurováno?
-
Můžeme použít příkaz ping na server?
-
Jsou DLL pro naše připojení a ovladače databáze ve vyhledávacích
cestách?
Aplikace může používat datové zdroje ODBC (např. Sybase).
Konfigurace ovladače ODBC vyžaduje:
-
Výrobcem podporovaný ODBC ovladač.
-
Správce ovladačů ODBC.
-
Administrátor ODBC.
K nastavení přezdívky ODBC pro připojení ovladačem ODBC použijeme
Administrátor BDE.
Odpojení od databázového
serveru
Jsou dva způsoby odpojení komponenty databáze od serveru:
-
Nastavíme vlastnost Connected na false.
-
Voláme metodu Close.
Nastavení Connected na false volá Close.
Close
uzavírá všechny otevřené datové množiny a odpojuje je od serveru. Např.
následující kód uzavírá všechny aktivní datové množiny komponenty databáze
a ukončuje její připojení:
Database1->Connected = false;
Uzavírání datových
množin bez odpojování od serveru
Jsou situace, kdy chceme uzavřít všechny datové množiny,
bez odpojení od databázového serveru. K uzavření všech otevřených datových
množin bez odpojení od serveru provedeme tyto kroky:
-
Nastavíme vlastnost KeepConnection komponenty databáze
na true.
-
Voláme metodu CloseDataSets komponenty databáze.
Procházení
datovými množinami komponenty databáze
Komponenta databáze poskytuje dvě vlastnosti, které umožňují
aplikaci procházet všemi datovými množinami přiřazenými ke komponentě:
DataSets
a DataSetCount.
DataSets je indexované pole všech aktivních datových
množin (TTable, TQuery a TStoredProc) pro komponentu
databáze. Aktivní datové množiny jsou ty které jsou otevřeny. DataSetCount
je celočíselná hodnota určená pouze pro čtení, specifikující počet současně
aktivních datových množin.
DataSets s DataSetCount můžeme použít k
procházení všemi aktivními datovými množinami v kódu. Např. následující
kód prochází všemi aktivními datovými množinami a nastavuje vlastnost CachedUpdates
pro všechny datové množiny typu TTable na true:
for (int i = 0; i < pDatabase->DataSetCount;
i++)
if (pDatabase->DataSets[i]->ClassNameIs("TTable"))
pDatabase->DataSets[i]->CachedUpdates
= true;
Zpracování transakcí
Když vytvoříme databázovou aplikaci, pak C++ Builder poskytuje
řízení transakcí pro všechen databázový přístup. Transakce je skupina akcí,
které musí být úspěšně provedeny v jedné nebo více tabulkách databáze dříve
než jsou zapsány (stanou se trvalými). Pokud některá z těchto akcí je neúspěšná,
pak všechny akce transakce jsou zrušeny. Transakce zajišťují konzistentnost
databáze i při vzniku hardwarových chyb. Také udržují integritu dat při
souběžném víceuživatelském přístupu.
Např. v bankovní aplikaci, převádějící částku z jednoho
účtu na jiný účet je operace, kterou je vhodné chránit transakcí. Pokud
po odečtení částky z jednoho účtu nastane chyba která zabání v přičtení
částky na druhý účet, pak je vhodné zrušit celou transakci, neboť neproběhla
celá.
Normálně C++ Builder poskytuje pro naši aplikaci implicitní
řízení transakcí pomocí BDE. Když aplikace je pod implicitním řízením transakcí,
pak C++ Builder používá oddělené transakce pro každý záznam v datové množině,
který je zapsán do připojené databáze. Implicitní řízení transakcí minimalizuje
konflikty aktualizací a udržuje konzistentnost databáze. Na druhé straně,
protože každý řádek zapisovaný do databáze tvoří vlastní transakci, implicitní
řízení transakcí zvyšuje provoz v síti a zpomaluje aplikaci.
Pokud transakce řídíme explicitně, můžeme volit vhodnější
doby ke spuštění, dokončení a zrušení našich transakcí. Když vyvíjíme klientskou
aplikaci ve víceuživatelském prostředí, obzvláště když aplikace pracuje
se vzdáleným SQL serverem (jako je Sybase, Oracle, Microsoft SQL nebo InterBase)
nebo vzdálenou ODBC databází, pak musíme transakce řídit explicitně.
Poznámka: Pokud používáme odložené aktualizace,
pak můžeme minimalizovat počet transakcí nutných pro použití v naši aplikaci.
Používání explicitních transakcí
Jsou dva zásadně odlišné způsoby explicitního řízení transakcí
v databázových aplikacích:
-
Použijeme metody a vlastnosti komponenty databáze, jako je
StartTransaction,
Commit,
Rollback,
InTransaction
a TransIsolation.
-
V komponentě TQuery použijeme průchozí SQL. Průchozí
SQL je použitelný pouze ve verzi Client/Server, kde používáme SQL Links
k předávání příkazů SQL přímo na vzdálený SQL nebo ODBC server.
Hlavní výhodou použití metod a vlastností komponenty databáze
k řízení transakcí je to, že poskytuje čisté, přenositelné aplikace, které
nejsou závislé na konkrétní databázi nebo serveru. Hlavní výhodou použití
průchozího SQL je to, že můžeme používat rozšířené možnosti správy transakcí
konkrétního databázového serveru (je zapotřebí se seznámit s tímto modelem
v dokumentaci databázového serveru).
Jednovrstvové aplikace nemohou používat průchozí SQL.
Můžeme použít komponentu databáze k vytvoření explicitních transakcí pro
lokální databáze. Jsme ale omezeni na lokální transakce.
Používáni komponenty databáze pro transakce
Když spustíme transakci, pak všechny následující příkazy,
které čtou z a zapisují do databáze patří do této transakce. Každý příkaz
je nedílnou součástí skupiny. Změny musí být úspěšně zapsány do databáze
nebo všechny změny provedené ve skupině musí být zrušeny.
Položme si ještě otázku, jak dlouho má trvat transakce?
V ideálním případě pouze tak dlouho, jak je nezbytné. Čím déle je transakce
aktivní, tím více uživatelů, kteří současně přistupují k databázi a více
souběžných transakcí je zahájeno a ukončeno během života naší transakce,
čímž se zvyšují konflikty mezi transakcemi, když přistoupíme k zápisu našich
změn.
Když použijeme komponentu databáze, pak kód jedné transakce
je tento:
-
Spustíme transakci voláním metody StartTransaction
databáze.
-
Když transakce je spuštěna, pak všechny následující databázové
akce patří do transakce dokud transakce není explicitně ukončena. Testováním
vlastnosti InTransaction komponenty databáze můžeme zjistit zda
transakce probíhá. V průběhu transakce, data která vidíme v databázových
tabulkách, je určeno úrovní izolací transakcí.
-
Když všechny akce tvořící transakci proběhnou úspěšně, pak
všechny provedené změny uděláme trvalými voláním metody Commit komponenty
databáze. Commit obvykle umisťujeme do příkazu try...catch.
Pokud transakce nemůže být úspěšně dokončena, pak se můžeme pokusit o zpracování
chyby a případně operaci zopakovat nebo transakci zrušit.
-
Pokud v průběhu transakce se vyskytne chyba, pak můžeme chtít
zrušit všechny změny provedené transakci. K zrušení těchto změn použijeme
metodu Rollback komponenty databáze.
Rollback obvykle používáme v:
-
V kódu zpracování výjimky, když se nemůžeme zotavit z databázové
chyby.
-
V obsluze události pro stisknutí tlačítka Cancel nebo
podobné volbě v nabídce.
TransIsolation specifikuje úroveň izolací transakcí
pro transakce komponenty databáze. Úroveň izolací transakcí určuje jak
transakce jsou ovlivněny jinými souběžnými transakcemi, které pracují se
stejnými tabulkami. Určuje jak transakce "vidí" změny ostatních transakcí
v tabulce. Implicitní nastavení pro TransIsolation je tiReadCommitted.
Následující tabulka uvádí přehled možných hodnot TransIsolation
a popisuje jejich význam:
Úroveň izolace |
Význam |
tiDirtyRead |
Povoluje čtení neukončených změn vytvořených ostatními
souběžnými transakcemi databáze. Neukončené změny nejsou trvalé a mohou
být kdykoliv zrušeny. Tato úroveň nejméně izoluje od změn prováděných jinými
transakcemi. |
tiReadCommitted |
Povoluje čtení pouze dokončených (trvalých) změn provedených
v databázi ostatními souběžnými transakcemi. Je to implicitní úroveň izolace. |
tiRepeatableRead |
Povoluje jedno jednorázové čtení databáze. Naše transakce
nevidí změny na datech provedených ostatními transakcemi. Tato úroveň izolace
zajišťuje to, že když naše transakce opakovaně čte záznam, pak získáme
nezměněný záznam. Tato úroveň izolací nejvíce izoluje od změn provedených
ostatními transakcemi. |
Databázové servery mají různou podporu pro tyto úrovně
izolací. Pokud požadovaná úroveň izolací není serverem podporována, pak
C++ Builder použije nejbližší vyšší úroveň izolace.
Poznámka: Když používáme transakce s lokálními
tabulkami Paradoxu, dBASE, Access nebo FoxPro, pak nastavíme TransIsolation
na tiDirtyRead místo použití implicitního tiReadCommitted.
Pokud pro lokální tabulky máme nastavenou jinou úroveň izolace než tiDirtyRead,
pak BDE vrací chybu.
Jestliže aplikace používá ODBC ke spolupráci se
serverem, pak ovladač ODBC musí také podporovat požadovanou úroveň izolace.
Používání průchozího SQL
S průchozím SQL používáme komponentu TQuery, TStoredProc
nebo TUpdateSQL k zasílání příkazů řízení transakcí SQL přímo na
vzdálený databázový server. BDE tyto příkazy nezpracovává. Použití průchozího
SQL umožňuje převzít výhody řízení transakcí nabízených naším serverem
a to obzvláště když toto řízení je nestandardní.
Pro použití průchozího SQL k řízení transakcí musíme:
-
Instalovat správně ovladače SQL Links. Pokud při instalaci
C++ Builderu zvolíme standardní instalaci, pak ovladače SQL Links jsou
nainstalovány dobře.
-
Konfigurovat správně náš síťový protokol.
-
Mít přístup k databázi na vzdáleném serveru.
-
Použít průzkumníka SQL k nastavení SQLPASSTHRUMODE
na NOT SHARED.
Poznámka: Když SQLPASSTHRUMODE je NOT
SHARED, pak musíme oddělit komponenty databáze pro datové množiny které
předávají transakce SQL na server a datové množiny, které je nepředávají.
SQLPASSTHRUMODE specifikuje zda BDE a příkazy
průchozího SQL mohou být sdíleny stejným databázovým připojením. SQLPASSTHRUMODE
je většinou nastaveno na SHARED AUTOCOMMIT. Pokud ale chceme
používat průchozí SQL, pak jej musíme nastavit na NOT SHARED (musíme
mít samostatnou komponentu databáze pro komponentu TQuery, která
předává příkazy transakcí SQL na server a další komponenty datových množin,
které to nedělají).
Používání lokálních transakcí
BDE podporuje lokální transakce na tabulkách Paradoxu a dBASE.
Z hlediska kódování není rozdíl mezi lokálními transakcemi a transakcemi
na vzdáleném databázovém serveru. Když transakce je zahájena na lokální
tabulce, pak provedené změny jsou zaznamenány. Každý zaznamenaný záznam
obsahuje vyrovnávací paměť pro původní záznam. Když transakce je aktivní,
pak aktualizovaný záznam je uzamčen dokud transakce není ukončena voláním
Commit
nebo
Rollback. Při Rollback je k obnovení původního stavu
použit záznam z vyrovnávací paměti původního záznamu.
Pro lokální transakce platí tato omezení:
-
Není podporováno automatické obnovování dat.
-
Nejsou podporovány příkazy definice dat.
-
Transakce nemohou být spuštěny na dočasných tabulkách.
-
Pro Paradox, lokální transakce mohou být prováděny pouze
na tabulkách s přípustnými indexy. Nelze zrušit změny v tabulkách Paradoxu,
které nejsou indexovány.
-
Je omezen počet záznamů, které mohou být uzamčeny a modifikovány.
Pro tabulky Paradoxu je to 255 záznamů a pro dBASE 100 záznamů.
-
Transakce nemohou být spuštěny pro ovladač BDE ASCII.
-
Úroveň izolací transakcí musí být nastavena pouze na tiDirtyRead.
-
Nelze uzavírat kurzor na tabulce během rušení transakce.
Aplikování odložených aktualizací
BDE poskytuje podporu pro odložené aktualizace. Při odložených
aktualizacích, naše aplikace získá data z databáze, provede všechny změny
lokálně na kopii dat a aplikuje odložené aktualizace na datovou množinu
najednou. Odložené aplikace jsou aplikovány na databázi v jedné transakci.
Odložené aktualizace mohou minimalizovat čas transakce
a omezovat síťový provoz. Nicméně, odložená data jsou lokální v naší aplikaci
a tedy nejsou pod řízením transakcí. Pracujeme na těchto datech lokálně,
zatímco ostatní aplikace mohou měnit tato data v databázových tabulkách.
Tyto změny nevidíme, dokud naše odložené aktualizace neaplikujeme. Při
zápisu našich změn do databáze může vzniknout mnoho konfliktů.
Můžeme říci datové množině podporující BDE aby používala
odložené aktualizace pomocí vlastnosti CachedUpdates. Když změny
jsou kompletní, pak je můžeme aplikovat komponentou datové množiny, komponentou
databáze nebo speciální aktualizačním objektem. Když změny nemohou být
aplikovány na databázi bez speciálního zpracování (např. když pracujeme
se spojeným dotazem), pak musíme použít událost OnUpdateRocord k
zápisu změn do jednotlivých tabulek tvořících spojený pohled.
Poznámka: Pokud používáme odložené aplikace,
pak můžeme předpokládat přesun do vícevrstvové aplikace, neboť zde jsou
větší možnosti aktualizace.
Vytváření a restrukturalizace databázových tabulek
V aplikacích založených na BDE, můžeme použít komponentu
TTable
k vytvoření nové databázové tabulky a k přidávání indexů k existujícím
tabulkám. Tabulky můžeme vytvářet při návrhu nebo za běhu. K vytvoření
tabulky musíme specifikovat položky v tabulce pomocí vlastnosti
FieldDefs
a případné indexy pomocí vlastnosti IndexDefs a voláme metodu CreateTable
(nebo v místní nabídce tabulky zvolíme
Create Table).
Poznámka: Když vytváříme tabulky Oracle8, pak
nemůžeme vytvářet objekty položek (ADT položky, položkové pole, odkazové
položky a položkové datové množiny).
Pokud chceme za běhu restrukturalizovat tabulku (jinak
než přidat indexy), pak musíme použít DbiDoRestructure API BDE.
Přidávat indexy k existující tabulce můžeme pomocí metody AddIndex
komponenty tabulky.
Poznámka: K restrukturalizaci tabulek Paradoxu
a dBASE při návrhu můžeme použít Desktop databáze. K vytváření a restrukturalizaci
tabulek na vzdálených serverech, používáme Průzkumník SQL a restrukturalizujeme
tabulky pomocí SQL.
Pochopení vztahu
mezi databází a komponentou sezení
Obecně, vlastnosti komponenty sezení, jako je KeepConnections,
poskytují globální, implicitní chování, které je aplikováno na všechny
dočasné komponenty databáze vytvářené podle potřeby za běhu aplikace.
Metody sezení jsou někdy aplikovány různě. Metody TSession
ovlivňují všechny komponenty databáze bez ohledu na jejich stav. Např.
metoda DropConnections sezení uzavírá všechny datové množiny náležející
komponentám databáze sezení a pak ukončuje všechna databázová připojení,
když vlastnost KeepConnection pro jednotlivé komponenty databáze
je true.
Metody komponenty databáze působí pouze na datové množiny
přiřazené k dané komponentě databáze. Např. předpokládejme že komponenta
databáze
Database1 je přiřazena k implicitnímu sezení. Pak
Database1->CloseDataSets();
uzavírá pouze ty datové množiny, které jsou přiřazeny
k Database1. Otevřené datové množiny patřící do jiných komponent
databází v implicitním sezení zůstávají otevřeny.
Používání
komponent databáze v datových modulech
Komponenty databáze můžeme bezpečně umisťovat do datových
modulů. Jestliže vložíme datový modul, který obsahuje komponentu databáze
do Zásobníku objektů, a chceme aby ostatní uživatelé od ní mohli dědit,
pak musíme nastavit vlastnost
HandleShared komponenty databáze na
true
k zabránění konfliktům globálního jmenného prostoru.
-
Pokuste se v nějaké aplikaci připojit k nějaké databázi vyžadující jméno
uživatele a heslo a vyzkoušejte různé způsoby zadávání těchto informací.
   |
12. Připojování k databázi
|