Il existe quatre modes de transaction dans SQL Server. L'un d'eux est le mode implicite.
Dans SQL Server, une transaction implicite est lorsqu'une nouvelle transaction est lancée implicitement lorsque la transaction précédente se termine, mais chaque transaction est explicitement terminée avec un COMMIT
ou ROLLBACK
déclaration.
Cela ne doit pas être confondu avec le mode autocommit, où la transaction est démarrée et terminée implicitement.
Les quatre modes de transaction
SQL Server peut fonctionner dans les modes de transaction suivants :
Mode de transaction | Description |
---|---|
Transaction de validation automatique | Chaque relevé individuel est une transaction. |
Transaction implicite | Une nouvelle transaction est lancée implicitement lorsque la transaction précédente se termine, mais chaque transaction est explicitement terminée, généralement avec un COMMIT ou ROLLBACK déclaration en fonction du SGBD. |
Transaction explicite | Commence explicitement par une ligne telle que START TRANSACTION , BEGIN TRANSACTION ou similaire, selon le SGBD, et explicitement validé ou annulé avec les instructions pertinentes. |
Transaction groupée | Applicable uniquement à plusieurs ensembles de résultats actifs (MARS). Une transaction explicite ou implicite qui démarre sous une session MARS devient une transaction de portée par lots. |
Mode implicite vs validation automatique
Dans SQL Server, certaines instructions démarrent automatiquement une transaction lors de leur exécution. C'est comme s'ils étaient précédés d'un BEGIN TRANSACTION
invisible déclaration.
Dans la plupart des cas, ces transactions sont également validées implicitement, comme s'il y avait un COMMIT TRANSACTION
invisible déclaration. Ces transactions sont dites en mode autocommit .
Dans d'autres cas, il n'y a pas de COMMIT TRANSACTION
invisible pour correspondre à l'invisible BEGIN TRANSACTION
déclaration. La transaction reste en cours jusqu'à ce que vous la validiez explicitement ou l'annuliez avec un COMMIT TRANSACTION
ou ROLLBACK TRANSACTION
déclaration. Dans ce cas, la transaction est dite en mode implicite .
Que la transaction s'exécute en mode implicite ou en mode autocommit dépend de votre IMPLICIT_TRANSACTIONS
réglage.
Déclarations qui démarrent une transaction implicite
Les instructions suivantes démarrent une transaction implicite dans SQL Server.
ALTER TABLE
BEGIN TRANSACTION
CREATE
DELETE
DROP
FETCH
GRANT
INSERT
OPEN
REVOKE
SELECT
(sauf ceux qui ne sélectionnent pas dans une table, commeSELECT GETDATE()
ouSELECT 1*1
)TRUNCATE TABLE
UPDATE
Chaque fois que vous exécutez ces instructions T-SQL, vous démarrez une transaction. La plupart du temps, la transaction sera automatiquement validée. Vous avez donc commencé et terminé la transaction sans avoir à le faire explicitement.
Cependant, selon votre IMPLICIT_TRANSACTIONS
paramètre, vous devrez peut-être valider la transaction explicitement.
Quand IMPLICIT_TRANSACTIONS
est OFF
Lorsque votre IMPLICIT_TRANSACTIONS
le paramètre est OFF
, les instructions ci-dessus effectuent des transactions en mode autocommit. Autrement dit, ils commencent et mettre fin implicitement à la transaction.
C'est comme avoir un BEGIN TRANSACTION
invisible et un COMMIT TRANSACTION
invisible déclaration, le tout à partir d'une seule déclaration.
Dans ce cas, vous n'avez rien à faire pour valider ou annuler la transaction. C'était déjà fait pour vous.
Quand IMPLICIT_TRANSACTIONS
est ON
Lorsque votre IMPLICIT_TRANSACTIONS
le réglage est ON
, les instructions ci-dessus se comportent légèrement différemment.
Lorsque IMPLICIT_TRANSACTIONS
le réglage est ON
, les instructions ci-dessus obtiennent un BEGIN TRANSACTION
invisible mais ils ne reçoivent pas de COMMIT TRANSACTION
correspondant déclaration.
Cela signifie que vous devez explicitement valider ou annuler la transaction vous-même.
Cependant, lorsque le mode de transaction est implicite, aucun BEGIN TRANSACTION
invisible est émis si une transaction est déjà en cours.
Exemple
Voici un exemple pour illustrer le concept.
SELECT @@TRANCOUNT AS TransactionCount;
SET IMPLICIT_TRANSACTIONS OFF;
SELECT TOP 1 ProductName, ProductPrice FROM Products;
SELECT @@TRANCOUNT AS TransactionCount;
Résultat :
+--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected) Commands completed successfully. +-------------------------+----------------+ | ProductName | ProductPrice | |-------------------------+----------------| | Left handed screwdriver | 25.99 | +-------------------------+----------------+ (1 row affected) +--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected)
Dans ce cas, j'ai défini IMPLICIT_TRANSACTIONS
sur OFF
et exécutez le SELECT
déclaration. Cela signifiait que le SELECT
L'instruction a été exécutée en mode autocommit et, par conséquent, la transaction a été démarrée et terminée implicitement.
@@TRANCOUNT
renvoyé 0
, ce qui signifie qu'aucune transaction n'était en cours à ce stade.
Le voici à nouveau, sauf que cette fois nous avons défini IMPLICIT_TRANSACTIONS
sur ON
.
SELECT @@TRANCOUNT AS TransactionCount;
SET IMPLICIT_TRANSACTIONS ON;
SELECT TOP 1 ProductName, ProductPrice FROM Products;
SELECT @@TRANCOUNT AS TransactionCount;
Résultat :
+--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected) Commands completed successfully. +-------------------------+----------------+ | ProductName | ProductPrice | |-------------------------+----------------| | Left handed screwdriver | 25.99 | +-------------------------+----------------+ (1 row affected) +--------------------+ | TransactionCount | |--------------------| | 1 | +--------------------+ (1 row affected)
Le dernier @@TRANCOUNT
renvoie une valeur de 1
. Cela signifie que notre transaction est toujours en cours.
@@TRANCOUNT
renvoie le nombre de BEGIN TRANSACTION
déclarations qui se sont produites sur la connexion en cours. Nous n'en avons pas explicitement émis un, mais un a été implicitement émis.
Nous devons donc en fait valider cette transaction (ou l'annuler) afin de décrémenter le @@TRANCOUNT
jusqu'à 0
.
COMMIT TRANSACTION;
SELECT @@TRANCOUNT AS TransactionCount;
Résultat :
+--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected)
Ainsi, le code de notre transaction implicite aurait dû inclure le COMMIT
déclaration :
SELECT @@TRANCOUNT AS TransactionCount;
SET IMPLICIT_TRANSACTIONS ON;
SELECT TOP 1 ProductName, ProductPrice FROM Products;
COMMIT TRANSACTION;
SELECT @@TRANCOUNT AS TransactionCount;
Résultat :
+--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected) Commands completed successfully. +-------------------------+----------------+ | ProductName | ProductPrice | |-------------------------+----------------| | Left handed screwdriver | 25.99 | +-------------------------+----------------+ (1 row affected) Commands completed successfully. +--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected)
ANSI_DEFAULTS
Si vous constatez que les transactions implicites sont activées de manière inattendue, cela peut être dû au ANSI_DEFAULTS
paramètre.