Az implicit tranzakció, avagy Oracle vs MSSQL mármegint

A Millenárison tartott kiváló ITDEVCON rendezvényen részt vettem az Ask The Experts blokkban, mint SQL expert. Itt megint belefutottam a klasszikus esetbe, de árnyaltan: elmesélte egy szaktárs, hogy ő dolgozik Oracle-lel meg MSSQL-lel is, és az az ő baja a MSSQL-lel, hogy az nem tud olyat, mint az Oracle, vagyis a tranzakciókat nem lehet kényelmesen kezelni, hanem vagy az SQL Server jobban tudja, vagy pedig explicit begin tran-commit párt kell gépelni – míg az Oracle-ben nyugodtan dolgozhat, és amikor úgy gondolja, akkor commitot mond, addig meg gyűlik a redo logban a tranzakció adat. Legalábbis ő nem talált jobb megoldást. És megkérdezte, hogy vajon tudok-e én jobbat. Nos, én pedig, ki azon rugózok folyton, hogy az MSSQL enterspájz-ready, tudtam.

Az úgy van, hogy háromféle tranzakciókezelés van MSSQL-ben. Az alap az automatikus, amikor minden batchünket az SQL Server magától beteszi egy tranzakcióba, számunkra láthatatlanul és befolyásolhatatlanul. Ha azt mondjuk, hogy begin tran, akkor explicit tranzakciókezelésbe kezdünk, és tudjuk, hogy majd mondunk commit v rollback parancsot is a végén. Aki meg Oracle-n nőtt fel, az tuti hogy implicit tranzakciót fog használni. Ez attól nyílik meg, hogy kiadunk egy listázott kulcsszót (kicsit több, mint egy tucat van, a BOL-ban az igazság megint – tipikusan INSERT, UPDATE, DELETE, CREATE, DROP, stb.), és addig tart, amíg azt nem mondjuk, hogy commit. Tehát a nyitása az implicit rész. Azt kell tudni, hogy csak akkor nyílik új tranzakció, ha nincs még nyitva tranzakció. Ez a tulajdonság kapcsolatonként állítható egy SET opcióval.

Nézzünk egy egyszerű példát:

use tempdb
create table t1 (a int)
GO
-- bekapcsoljuk az implicit tranzakciókezelest
set implicit_transactions on

select @@TRANCOUNT --1, mert a SELECT kulcsszo is nyit tranzakciot!
insert into t1 values(1);

select @@TRANCOUNT -- meg mindig 1, es ugyanaz az egy
insert into t1 values(2);

select @@TRANCOUNT -- meg mindg az az 1
rollback

select @@TRANCOUNT -- 1, de ez mar egy uj
select * from t1 -- ez pedig töküres, mindkét sort kitörölte a rollback

implicit_tranJa, és ezt lehet állandóra is állítani, ha vki perverz, SSMS-ben a tools-options pont alatt a Query Editor – SQL Server – ANSI helyen, lásd mellékelt ábra. Enjoy! És ne felejtsétek el, hogy aki utoljára megy haza, kommitoljon mindenki helyett…

3 Comments

  1. S.E.:

    Jó a cikk, de szerény véleményem szerint az implicit tranzakciók használatának lehetősége egy butaság. Igazából nem tudod kontrollálni, hogy mikor kezdődik egy tranzakció. A default működés a jó: vagy minden utasítás implicit tranzakcióban van, vagy én indítom és zárom le.

    My 2 cents.

  2. Erik:

    A konkurrencia-kompatibilitas soha nem butasag ebben a vilagban :) amugy szerintem egy kivalo lehetoseg a labonlovesre valoban. en most hasznaltam masodjara a fenti demo elkeszitesehez, az elso hasznalat kb akkor volt, mikor megtudtam, hogy van ilyen, es kiprobaltam.

  3. S.E.:

    Oké, legyen kompatibilis a konkurrenciával…ezen kívül viszont másra nem jó. Sőt, oltári nagy szívásokat eredményez annak, aki erről a hülyeségről nem tud. Megnyitja és lezárja a tranzakcióját, de az mégsem kerül lezárásra, mert a @@trancount akkor még mindig 1…OMFG!

Leave a comment