none
SQL Server 2005 - zamyká SELECT tabulky?

    Dotaz

  • Dobrý den,

    Mám dotaz:

    V naší firmě vytvářím dotazy - často i komplikované, déletrvající - do "ostré" databáze ERP systému běžící v SQL Serveru 2005, tzn obcházím klienta ERP systému a prohledávám rovnou tabuky DB.

    Chci se zeptat, jak je to se zamykáním tabulek v této DB, když používám pouze a výhradně příkaz SELECT (DISTINCT)? Zamykám tabulky pro další použití klientem ERP systému? Jak je to v případě, že se neptám přímo do tabulky, ale do View? Zamykají se tabulky, nebo ne?

    Myslím si, že toto je pro Vás opravdu směšný dotaz, ale bojuji s tím čím dál víc a já opravdu netuším, co se odehrává, specialista na DB v SQL 2005 nejsem, pouze jsem pochopil strukturu tabulek dat našeho systému a vím, co chci a musím s čím spojit tak, abych dostal správný výsledek a v průběhu let jsem se naučil selektit a joinovat a další jednoduché funkce...

    Díky moc.

    1. října 2010 8:35

Odpovědi

  • Dobrý den,

    pokud používáte příkaz SELECT v rámci připojení s defaultním nastavením, budou se v závislosti na množství vybíraných záznamů zamykat sdílenými zámky jednotlivé řásky, datové stránky nebo celá tabulka. Tím SQL Server zaručuje, že načtete pouze "čistá" data, tedy data, na kterých aktuálně neprobíhá žádná změna. To je díky defaultní izolaci transkací, která je READ COMMITTED.

    Možností, jak se s tím poradit, je více. Preferovanou cestou by mělo být oddělení Vašich dotazů od transakční zátěže generované z ERP, abyste neblokoval uživatele ERP systému. Ideální cestou je datový sklad, případně zrcadlení, log shipping nebo replikace dat do oddělené databáze.

    Druhou cestou je změna izolační úrovně. Pokud se chcete zbavit vzájemného blokování výběrů a změn dat, doporučil bych snapshot izolační úroveň. Je možné u Vašich SELECTů použít i hint NOLOCK - v tom případě ale zapomeňte na konzistenci načtených dat.

    S pozdravem

    Miloslav Peterka

    30. listopadu 2010 7:43

Všechny reakce

  • Koukám, že tady nikdo moc nepříspívá... OK, literatura říká následující:

    Tabulku lze uzamknout i při příkazu SELECT pomocí tzv. Table hintů, např.:

    -- toto je tzv. sdílené uzamčení, které zabraňuje tomu, aby byla data pozměněna z jin instance
    SELECT * FROM SomeTable WITH (TABLOCK) 

    Zamykat lze i menší entity, než celé tabulky, např. 8 KB stránky, nebo jen jednotlivé řádky. Ještě existuje Výhradní uzamčení, které se aplikuje před vlastní aktualizací dat a zabraňuje aktualizaci z více míst najednou a Uzamčení pro Update (Update lock), které se aplikuje na entity, které "mohou být" aktualizované. Update lock je povolen jen z jedné instance a nebrání jiným instancím ve sdíleném uzamčení datové entity.

    Výše uvedeným popisem nejsou zdaleka vyčerpané všechny možnosti... Existují další způsoby uzamčení a rovněž si můžete zahrávat s nastavením transakcí, více je popsané u příkazu SET TRANSACTION ISOLATION LEVEL.

    Otázkou je, jak je na takovou eventualitu externího uzamčení připraven váš ERP systém. Pokud použijete jiné zamykací schéma, než které použili vývojáři ERP systému, může v krajním případě dojít k deadlockům na kterékoli straně.

    U view se (dle logiky jejich vytváření) nejspíše zamknou všechny tabulky, ze kterých je view vytvořeno.

    Možná byste mohl zvážit, zda pro vaše "déle trvající" dotazy nevytvořit další instanci databáze, která by byla replikovanou kopií nebo zrcadlem produkce. Uživatelé produkčního systému mohou pracovat bez omezení a pokud replikaci pozastavíte, máte i vy jistotu, že data budou stabilní, zamykání vás vůbec nemusí trápit a i záloha udělaná tímto způsobem se někdy může hodit...

     

    5. listopadu 2010 17:06
  • Dobrý den,

    pokud používáte příkaz SELECT v rámci připojení s defaultním nastavením, budou se v závislosti na množství vybíraných záznamů zamykat sdílenými zámky jednotlivé řásky, datové stránky nebo celá tabulka. Tím SQL Server zaručuje, že načtete pouze "čistá" data, tedy data, na kterých aktuálně neprobíhá žádná změna. To je díky defaultní izolaci transkací, která je READ COMMITTED.

    Možností, jak se s tím poradit, je více. Preferovanou cestou by mělo být oddělení Vašich dotazů od transakční zátěže generované z ERP, abyste neblokoval uživatele ERP systému. Ideální cestou je datový sklad, případně zrcadlení, log shipping nebo replikace dat do oddělené databáze.

    Druhou cestou je změna izolační úrovně. Pokud se chcete zbavit vzájemného blokování výběrů a změn dat, doporučil bych snapshot izolační úroveň. Je možné u Vašich SELECTů použít i hint NOLOCK - v tom případě ale zapomeňte na konzistenci načtených dat.

    S pozdravem

    Miloslav Peterka

    30. listopadu 2010 7:43
  • Děkuji všem přispěvatelům za obsáhlé odpovědi.

    Toto téma považuji za odpovězené.

    Karel Hrubeš


    Karel Hrubeš
    23. února 2011 14:51