sql >> Database >  >> RDS >> Sqlserver

Waarom een ​​TSQL-instructieblok invoegen als het transactie-isolatieniveau voor een andere transactie serialiseerbaar is met een niet-conflicterend filter?

Het eerste probleem in uw testscenario is dat de tabel geen bruikbare index heeft op firstname . De tweede is dat de tafel leeg is.

Van Toetsenbereikvergrendeling in BOL

Er is geen geschikte index om RangeS-S te nemen vergrendelt dus om serialiseerbare semantiek te garanderen, moet SQL Server de hele tabel vergrendelen.

Als u probeert een geclusterde index toe te voegen aan de tabel in de kolom met de voornaam, zoals hieronder, en het experiment herhaalt ...

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

... je zult merken dat je nog steeds geblokkeerd bent!

Ondanks het feit dat er nu een geschikte index bestaat en het uitvoeringsplan laat zien dat er naar wordt gezocht om aan de vraag te voldoen.

U kunt zien waarom door het volgende uit te voeren

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 

Retourneren

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

SQL Server verwijdert niet zomaar een bereikvergrendeling op precies het bereik dat u opgeeft in uw zoekopdracht.

Voor een gelijkheidspredikaat op een unieke index, als er een overeenkomende sleutel is, is er gewoon een normaal slot nodig in plaats van welk type bereikslot dan ook.

Voor een niet-uniek zoekpredikaat verwijdert het sloten op alle overeenkomende sleutels binnen het bereik plus de "volgende" aan het einde van het bereik (of op ffffffffffff om oneindigheid weer te geven als er geen "volgende" sleutel bestaat). Zelfs verwijderde "ghost"-records kan worden gebruikt in dit bereik sleutelvergrendeling.

Zoals hier beschreven voor een gelijkheidspredikaat op een unieke of niet-unieke index

Dus met een lege tabel de SELECT eindigt nog steeds met het vergrendelen van de hele index. U moet ook eerder een rij hebben ingevoegd tussen abc en lmn en dan zou je invoeging slagen.

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


  1. 6 redenen waarom Microsoft Access uw bedrijf kan helpen

  2. MYSQL:verschil tussen binair en Blob

  3. Laravel join-query's AS

  4. Facebook-achtige meldingen volgen (DB Design)