web-dev-qa-db-fra.com

Mettre à jour les instructions avec un niveau d'isolement de transaction défini lu non validé

Si j'ai une procédure stockée avec set transaction isolation level read uncommitted, Cela affectera-t-il les instructions de mise à jour?

Je sais que vous ne devez pas utiliser with (nolock) sur les instructions de mise à jour/suppression, et cela fait à peu près la même chose mais je ne sais pas si SQL l'ignore sur les instructions de mise à jour dans la procédure ou si je dois faire attention à ne pas utiliser s'il y a des instructions de mise à jour.

ÉDITER:

Désolé pour la confusion. Je n'essaie pas de comprendre quel serait l'effet de l'utilisation de ce type de verrouillage sur les instructions de manipulation ou si c'est une bonne idée. En fait, je ne veux PAS utiliser ce type de verrouillage sur les instructions de manipulation, et donc ma question est de savoir si mettre "set transaction ..." en haut de mon proc stocké sera jamais honoré par les instructions update/delete ou si il sera ignoré. J'espère que c'est juste ignoré.

Je suis pleinement conscient des effets (avec ses avantages et ses inconvénients) que cela aura sur certaines déclarations.

7
BVernon

Le "niveau d'isolement des transactions" affecte principalement (à ma connaissance) le comportement de l'opération de lecture, c'est-à-dire si une opération de lecture émettra des verrous. Dans le cas de "lecture non validée", voici une citation de MSDN

Les transactions s'exécutant au niveau LIRE NON COMMIS n'émettent pas de verrous partagés pour empêcher d'autres transactions de modifier les données lues par la transaction en cours. Les transactions READ UNCOMMITTED ne sont pas non plus bloquées par des verrous exclusifs qui empêcheraient la transaction en cours de lire les lignes qui ont été modifiées mais non validées par d'autres transactions

Par conséquent, à votre question, la réponse est NON, la mise à jour ne sera pas affectée par le niveau d'isolement des transactions "lecture non validée" à l'intérieur de la même procédure stockée.

- Mise à jour (un exemple pour prouver cette logique) Dans SSMS, nous ouvrons deux fenêtres, et dans la fenêtre 1 (W1 ci-après), exécutons ce qui suit

use tempdb
create table dbo.t (a int)
go
insert into dbo.t (a) values (10)
go
begin tran
update dbo.t 
set a = 20
where a = 10

-- commit tran

Dans une autre fenêtre (W2), exécutez ce qui suit (voir les commentaires pour le comportement)

use TempdB
set transaction isolation level read uncommitted
select * from dbo.t -- you can have dirty read, showing [a]=20, which is an uncommitted UPDATE in W1

go
-- the following update will wait (before proper locks are granted)
update dbo.t 
set a = 30
where a= 10

Cela signifie que l'instruction UPDATE dans W2 (avec READ UNCOMMITTED) n'est pas affectée par le niveau d'isolement de transaction (c'est-à-dire se comporte toujours comme prévu) comme l'instruction SELECT.

- MISE À JOUR 2: Selon MSDN MISE À JOUR t-sql,

AVEC (Table_Hint_Limited)

Spécifie une ou plusieurs indications de table autorisées pour une table cible. Le mot clé WITH et les parenthèses sont obligatoires. NOLOCK et READUNCOMMITTED ne sont pas autorisés. Pour plus d'informations sur les conseils de table, consultez Conseils de table (Transact-SQL).

Donc, je comprends que lorsque vous exécutez l'instruction UPDATE, dans SQL Server, il n'y a aucun moyen que vous puissiez mettre à jour les données sales (c'est-à-dire les données non validées) même si vous pouvez lire les données sales dans votre session.

3
jyao

Si j'ai une procédure stockée avec un niveau d'isolement de transaction défini lu non engagé, cela affectera-t-il les instructions de mise à jour?

La lecture non validée permet des lectures incorrectes. Un verrou X sera pris sur la ligne ou au niveau supérieur (dans la page de données ou l'index) avant qu'il ne soit rendu sale. Les lignes accessibles directement par la requête lors de la recherche d'une ligne à mettre à jour prendront un verrou U et seront bloquées.

Cependant, il est toujours possible qu'une mise à jour soit affectée par le niveau d'isolement.

Connexion 1

CREATE TABLE T1
(
X INT NULL,
Y INT NULL
);

INSERT INTO T1 DEFAULT VALUES;

BEGIN TRAN
UPDATE T1 SET X = 100;    

WAITFOR DELAY '00:00:10'

ROLLBACK;

Connexion 2 (exécutez-la dans les 10 secondes suivant le déclenchement de la connexion 1)

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

UPDATE T1
SET    Y = (SELECT SUM(X)
            FROM   T1);

SELECT *
FROM   T1; 

Résultat

enter image description here

L'opération de lecture a lu la valeur non validée et le résultat final a été utilisé dans le UPDATE même si le 100 qui a été lu a finalement été annulé.

5
Martin Smith

En fonction de votre modification, la question est maintenant plus claire.

donc ma question est de savoir si mettre "set transaction ..." en haut de mon proc stocké sera jamais honoré par les instructions update/delete ou s'il sera ignoré.

Le niveau d'isolement des transactions doit être pensé en termes d'opérations de lecture. Les niveaux d'isolement contrôlent la façon dont les opérations de lecture sont protégées des autres opérations d'écriture.

Le moteur de base de données régit le comportement de verrouillage de toutes les opérations d'écriture et vous ne pouvez pas modifier ce comportement au niveau de la base de données.

De BOL :

Tous les niveaux d'isolement émettent toujours des verrous exclusifs pour les opérations d'écriture et maintiennent les verrous pendant toute la durée de la transaction.

Lisez:

3
Kin Shah