Autor Téma: NeatomickaADO transakce z D2010 na MSSQL 2005  (Přečteno 1678 krát)

pf1957

  • Host
NeatomickaADO transakce z D2010 na MSSQL 2005
« kdy: 14-07-2010, 15:54:59 »
Ahoj vsichni, narazil jsem na problem, nad kterym mi zustava rozum stat...

1. V DB jsou tabulky  A, B a C

2. Tabulka A ma mj. after insert/update trigger, ktery kopiruje zaznamy do jine MSSQL DB, ke ktere nemam prava pristupu (takze bych ocekaval exception a zadna data vlozena do DB).

3. v explicitni ReadCommited transakci vkladam data, schematicky asi takhle:

Kód: [Vybrat]
DB.BeginTrans;
try
  select from C
  select from B
  if B.FK is not null
     update(A)
  else
     insert(A)
     select @@Identity
     insert(B)
  DB.CommitTrans;
except
  ...


Pro nektere SQL prikazy pouzivam ruzne instance TADOQuery, kterym prirazuji jedno spolecne connection se zahajenou ReadCommitted transakci, ktere po celou dobu indikuje, ze je InTransaction.

4. Vsechno probehne bez chyb, po insertech to vraci RowsAffected=1
5. Na serveru je po skonceni transakce tabulka A prazdna (!), ale tabulka B obsahuje vlozena data.

6. Kdyz ty prikazy napisu rucne do okna v Management studiu, tak to vyhodi chybu

Kód: [Vybrat]
(1 row(s) affected)
Msg 916, Level 14, State 1, Procedure tr_customer_from_xxx, Line 49
The server principal "xxx" is not able to access the database "XXX" under the current security context.

a nikam se nic neulozi, takze se to chova korektne.

--

Nenapado nekoho, co je spatne?

1. proc to nehlasi chybu po insertu do tabulky, u ktere selze trigger?
2. jak to, ze transakce neni atomicka?
Vypada to, jako kdyby se pracovalo v rezimu autocommit, ale o tom se pise, ze jakmile se nastartuje explicitni transakce, tak se vypina a pri vtrasovani do ADODB to vypada, ze az na hranici OLE je to OK...


sthruska (Stanislav Hruška)

  • Host
NeatomickaADO transakce z D2010 na MSSQL 2005
« Odpověď #1 kdy: 14-07-2010, 16:26:00 »
insert(A)
select @@Identity
insert(B)
DB.CommitTrans;

Nie je problém v tom, že chceš načítavať z tabuľky A a pritom údaje nie sú ešte uložené?

Stanislav Hruška

pf1957

  • Host
NeatomickaADO transakce z D2010 na MSSQL 2005
« Odpověď #2 kdy: 14-07-2010, 16:44:00 »
sthruska Napsal:

> Nie je problém v tom, že chceš načítavať z tabuľky
> A a pritom údaje nie sú ešte uložené?

Ne:

- v transakci vidis na svoje uncommitted data
- ale ja z tabulky A nectu. Ctu promennou @@Identity, ktera obsahuje vygenerovany umely PK pro tabulku A


JiriFol

  • Host
NeatomickaADO transakce z D2010 na MSSQL 2005
« Odpověď #3 kdy: 14-07-2010, 17:40:59 »
> 2. Tabulka A ma mj. after insert/update trigger, ktery

> kopiruje zaznamy do jine MSSQL DB, ke ktere nemam prava

> pristupu (takze bych ocekaval exception a zadna data vlozena do DB).

Nejspíš to nebude příčina problému, ale s MSSQL 7 jsem měl problémy s transakcemi přes linkované servery - v některých případech se

mi to vůbec nepodařilo rozchodit (speciálně Pervasive SQL linkovaný přes ODBC). Pokud jsem to nezabalil do transakce, bylo všechno

OK.

JiriF

Příspěvek zaslán emailem

Mi.Chal

  • Host
NeatomickaADO transakce z D2010 na MSSQL 2005
« Odpověď #4 kdy: 14-07-2010, 22:23:59 »
Sice to moc nesouvisi s tim na co se ptas, ale to @@identity bys mel lepsi nahradit treba scope_identity. Az nekdo udela nad tabulkou A trigger a v nem neco vlozi do nejaky jiny tabulky s autoincrement sloupcem, tak se budes divit, proc ti to prestalo fungovat.


pf1957

  • Host
NeatomickaADO transakce z D2010 na MSSQL 2005
« Odpověď #5 kdy: 15-07-2010, 09:27:00 »
Mi.Chal Napsal:

> Sice to moc nesouvisi s tim na co se ptas, ale to
> @@identity bys mel lepsi nahradit treba
> scope_identity. Az nekdo udela nad tabulkou A
> trigger a v nem neco vlozi do nejaky jiny tabulky
> s autoincrement sloupcem, tak se budes divit, proc
> ti to prestalo fungovat.

Diky za upozorneni - malem bych na to zapomel 8)

Ja tam puvodne to SCOPE_IDENTITY() dal, ale vracelo mi nulu, zatimco @@Identity ne, tak jsem to zatim odlozil. Ted uz jsem se podival 10 let stareho projektu, jak jsme to tenkrat delali - ze jsme museli sloucit insert+select do jednoho commandu - ten deBill musi mit vzdycky neco extra - normalne by to neslo ???

pf1957

  • Host
NeatomickaADO transakce z D2010 na MSSQL 2005
« Odpověď #6 kdy: 15-07-2010, 12:12:59 »
pf1957 Napsal:

> 1. proc to nehlasi chybu po insertu do tabulky, u
> ktere selze trigger?

Jak jsem prave zjistil, tak nekdo po ceste do Delphi (konkretne unit ADO) si s hlasenim chyb moc hlavu nelamal. Narazil jsem na dalsi chybu v triggeru, kterou MS Management studio korektne reportuje:

Kód: [Vybrat]
1 row(s) affected)
Msg 245, Level 16, State 1, Procedure tr_order_from_xxx, Line 28
Conversion failed when converting the varchar value 'CZK' to data type int.

ale v Delphi dostanu exception s textem:

Kód: [Vybrat]
Project Alcash.exe raised exception class EOleException with message
Conversion failed when converting the varchar value 'CZK' to data type int.

Zda se, ze ADO ve spojeni s Delphi je daleko vetsi shit, nez jsme cekali >:(


Mi.Chal

  • Host
NeatomickaADO transakce z D2010 na MSSQL 2005
« Odpověď #7 kdy: 17-07-2010, 01:35:59 »
pf1957 Napsal:
-------------------------------------------------------
> Jak jsem prave zjistil, tak nekdo po ceste do
> Delphi (konkretne unit ADO) si s hlasenim chyb moc
> hlavu nelamal.

vsak to taky neni nejnovejsi :)

> Narazil jsem na dalsi chybu v
> triggeru, kterou MS Management studio korektne
> reportuje:
1 row(s) affected)
> Msg 245, Level 16, State 1, Procedure
> tr_order_from_xxx, Line 28
> Conversion failed when converting the varchar
> value 'CZK' to data type int.
>
> ale v Delphi dostanu exception s textem:
Project
> Alcash.exe raised exception class EOleException
> with message
> Conversion failed when converting the varchar
> value 'CZK' to data type int.

vzdyt je to ta sama chyba, co se ti na tom nezda? Jestli nejak touzis po tom jak poznat, co to je za chybu, tak ta EOleException obsahuje nejaky property s Error kodem, z toho se pak da dohledat, co to je za typ chyby (treba ze nemas prava nebo objekt neexistuje). Tyhle chybovy kody jsou i nekde definovany, ale neni to pohromade - v D6 to bylo minimalne ve dvou souborech, jeden byl myslim db.pas


pf1957

  • Host
NeatomickaADO transakce z D2010 na MSSQL 2005
« Odpověď #8 kdy: 17-07-2010, 15:46:00 »
Mi.Chal Napsal:

> vzdyt je to ta sama chyba, co se ti na tom nezda?

To, ze Management studio reportuje modul, kde se to stalo:

Msg 245, Level 16, State 1, Procedure tr_order_from_xxx, Line 28
Coz je v tomto pripade dost podstatna informace pro to, abys chybu mohl lokalizovat. Bez toho je to docela problem, zejmena kdyz ten trigger uz je za hranici tvoji dodavky.

DanH

  • Host
NeatomickaADO transakce z D2010 na MSSQL 2005
« Odpověď #9 kdy: 17-07-2010, 16:10:59 »
Ale tahle hlasena chyba je bud:

Problemem toho trigeru, ze se snazi napasovat nekam neco, co tam nepatri -> at si autor trigeru opravi validaci na vstupu.
Tvoje aplikace nekontroluje pri odesilani co se kam snazi narvat, pak je problem na strane tveho programu, ze si nekontroluje co posila ven.

Idealne zkontrolovat na obou stranach.

Uzivatele aplikace prece vubec nezajima na kterem radku, ktere storedproc to selhalo.

Tohle by Ti mozna mohlo pomoct (koukni skoro na konec)
http://delphi.about.com/od/database/l/aa103001a.htm

D.

pf1957

  • Host
NeatomickaADO transakce z D2010 na MSSQL 2005
« Odpověď #10 kdy: 17-07-2010, 17:14:00 »
DanH Napsal:

> Problemem toho trigeru, ze se snazi napasovat
> nekam neco, co tam nepatri -> at si autor
> trigeru opravi validaci na vstupu.

No ano, ale potiz je v tom, ze kdyz insertnes data do tabulky a dostanes takovouhle chybu, tak musis docela pracne zjistovat, ze to nemas na svedomi ty, ale nekdo cizi.

Zatimco kdyz ten prikaz spustis rucne z Management studia, tak ti to primo napise,
ale spoustet rucne nektere slozitejsi prikazy rucne ss realnymi hodnotami je docela onanie.
> Uzivatele aplikace prece vubec nezajima na kterem
> radku, ktere storedproc to selhalo.

Nerozumim, proc do toho pletes uzivatele. Komu (neni uzivatel jako uzivatel) a jak se prezentuje chyba je uplne jiny problem.
> Tohle by Ti mozna mohlo pomoct (koukni skoro na
> konec) http://delphi.about.com/od/database/l/aa103001a.htm

Uz ten trigger opravili, ale az budu mit cas, tak tu chybu u nas v DB nasimuluju a urcite se podivam, jestli takova informace existuje nebo ne. Diky za tip.

--

Jinak tohle je celkem podruzny problem na dokreslesni primarniho problemu, kdy ADO  v Delphi nehlasi exception zadnou a misto toho pravdepodobne rollbackne transakci, takze jeji zbytek probehne v auto commit rezimu...


pf1957

  • Host
NeatomickaADO transakce z D2010 na MSSQL 2005
« Odpověď #11 kdy: 20-07-2010, 00:50:00 »
DanH Napsal:

> Tohle by Ti mozna mohlo pomoct (koukni skoro na
> konec)

Bohuzel nepomohlo, protoze

1. Connection.Errors[0] ma v description stejny text, jako zachycena exception
2. Connection.Errors[1] ma v description text The statement has been terminated.
3. V Source je u obou shodne Microsoft SQL native client
4. Cislo chyby je take shodne DB_E_INTEGRITYVIOLATION

ale podstatna informace, kde k chybe doslo tj. jmeno triggeru tam neni.

pepak

  • Host
NeatomickaADO transakce z D2010 na MSSQL 2005
« Odpověď #12 kdy: 20-07-2010, 07:47:00 »
K původnímu dotazu:

1. proc to nehlasi chybu po insertu do tabulky, u ktere selze trigger?

- Nevím, ADO nepoužívám. Myslím si, že právě v tomhle je jádro pudla. Doporučuji odkrokovat, nejlépe v CPU pohledu, abys měl jistotu, že to jde správnou větví a že kompilátor něco nezprasil (nebylo by to poprvé).

2. jak to, ze transakce neni atomicka?

- Jak ten kód chápu, tak je atomická, jen ji špatně vyhodnocuješ: Po INSERTu do A dojde k chybě (která z neznámých důvodů není hlášena), na to MSSQL reaguje zrušením operací v transakci, no a potom v nové transakci vkládáš do B a commituješ...

pf1957

  • Host
NeatomickaADO transakce z D2010 na MSSQL 2005
« Odpověď #13 kdy: 22-07-2010, 18:18:59 »
pepak Napsal:

> tomhle je jádro pudla. Doporučuji odkrokovat,
> nejlépe v CPU pohledu, abys měl jistotu, že to jde

To jsem samozrejme delal, nez jsem prisel na to, proc mi to nefunguje.

> - Jak ten kód chápu, tak je atomická, jen ji
> špatně vyhodnocuješ: Po INSERTu do A dojde k chybě
> (která z neznámých důvodů není hlášena), na to
> MSSQL reaguje zrušením operací v transakci, no a
> potom v nové transakci vkládáš do B a
> commituješ...

Jenomze pokud neco zrusilo mnou nastartovanou transakci, aniz by se  namahalo mi to dat na vedomi, tak by melo dojit k chybe pri commitu, ze delam commit nenastartovane transakce, pokud to moji nekdo z nejakeho duvodu uz ukoncil...


pf1957

  • Host
NeatomickaADO transakce z D2010 na MSSQL 2005
« Odpověď #14 kdy: 24-07-2010, 14:27:00 »
pepak Napsal:

> - Nevím, ADO nepoužívám.

A co tedy pouzivas proti MSSQL?

Uz jsem zase narazil na nereportovanou chybu, kdyz doslo k rekurzivnimu volani triggeru. Management studio nema problem chybu detekovat a spravne reportovat, zatimco ADO ji vubec nezachyti >:(