sql >> Databáze >  >> RDS >> Sqlserver

Proč vkládat blok příkazů TSQL, když je úroveň izolace transakce pro jinou transakci serializovatelná pomocí nekonfliktního filtru?

První problém ve vašem testovacím scénáři je, že tabulka nemá žádný užitečný index na firstname . Druhým je, že tabulka je prázdná.

Z Key-Range Locking v BOL

Neexistuje žádný vhodný index pro RangeS-S uzamkne, aby byla zaručena serializovatelná sémantika, kterou SQL Server potřebuje k uzamčení celé tabulky.

Pokud se pokusíte přidat seskupený index do tabulky do sloupce křestního jména, jak je uvedeno níže, a zopakujte experiment ...

CREATE CLUSTERED INDEX [IX_FirstName] ON [dbo].[dummy] ([firstname] ASC)

... zjistíte, že jste stále blokováni!

Navzdory skutečnosti, že vhodný index nyní existuje a prováděcí plán ukazuje, že se hledá, aby byl dotaz splněn.

Důvod můžete zjistit spuštěním následujícího

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

BEGIN TRAN

SELECT *
FROM   dummy
WHERE  firstname = 'abc'

SELECT resource_type,
       resource_description, 
       request_mode
FROM   sys.dm_tran_locks
WHERE  request_session_id = @@SPID

COMMIT 

Vrátí

+---------------+----------------------+--------------+
| resource_type | resource_description | request_mode |
+---------------+----------------------+--------------+
| DATABASE      |                      | S            |
| OBJECT        |                      | IS           |
| PAGE          | 1:198                | IS           |
| KEY           | (ffffffffffff)       | RangeS-S     |
+---------------+----------------------+--------------+

SQL Server nevyjímá pouze zámek rozsahu přesně pro rozsah, který zadáte ve svém dotazu.

Pro predikát rovnosti na jedinečném indexu, pokud existuje odpovídající klíč, bude zapotřebí pouze běžný zámek, nikoli jakýkoli typ zámku rozsahu.

Pro nejedinečný predikát hledání odstraní zámky na všech odpovídajících klíčích v rozsahu plus "další" na konci rozsahu (nebo na ffffffffffff reprezentovat nekonečno, pokud neexistuje žádný „další“ klíč). Dokonce i smazané „ghost“ záznamy lze v tomto rozsahu použít zamykání klíčem.

Jak je popsáno zde pro predikát rovnosti na jedinečném nebo nejedinečném indexu

Takže s prázdnou tabulkou SELECT stejně skončí uzamčením celého indexu. Také byste museli předtím vložit řádek mezi abc a lmn a pak by vaše vložka byla úspěšná.

insert into dummy values('def', 'def')


  1. Jak získat velikost tabulky v MySQL

  2. Instalace WordPressu pomocí WP-CLI

  3. Nastavte znakovou sadu a řazení sloupce v MariaDB

  4. Nelze exportovat databázi z mysql workbench