Que se passe-t-il si vous ne validez pas une transaction dans une base de données (par exemple, SQL Server)?

108

Supposons que j'ai une question:

begin tran
-- some other sql code

Et puis j'oublie de m'engager ou de revenir en arrière.

Si un autre client tente d'exécuter une requête, que se passe-t-il?

Charbel
la source

Réponses:

148

Tant que vous ne COMMITEZ pas ou ne ROLLBACK une transaction, elle est toujours «en cours» et potentiellement verrouillée.

Si votre client (application ou utilisateur) ferme la connexion à la base de données avant de valider, toutes les transactions en cours d'exécution seront annulées et arrêtées.

marc_s
la source
1
mmm, ok je suppose que cela créait une sorte de verrou. Je n'étais pas sûr que la fermeture de la connexion me sortirait réellement de cet état. le problème était que j'obtenais une erreur lorsque j'essayais de commettre. maintenant j'ai fermé la connexion et tout a fonctionné.
Charbel
12
Remarque: si vous utilisez Management Studio, la fermeture de la fenêtre de requête fermera la connexion
Joe Phillips
3
@BradleyDotNET: oui, définitivement
marc_s
2
Gardez à l'esprit que SQL Server Management Studio se valide automatiquement si vous fermez la fenêtre de requête / la connexion, par défaut.
Nuno du
1
Notez que lorsque le client ferme la connexion alors qu'une transaction est active, elle n'est pas toujours annulée - cela dépend du client et de la base de données. Par exemple, lorsqu'une application Java ferme une connexion à une base de données Oracle, toutes les connexions ouvertes sont automatiquement validées.
AviD le
38

Vous pouvez en fait essayer vous-même, cela devrait vous aider à comprendre comment cela fonctionne.

Ouvrez deux fenêtres (onglets) dans le studio de gestion, chacune d'elles aura sa propre connexion à SQL.

Vous pouvez maintenant commencer une transaction dans une fenêtre, faire des choses comme insérer / mettre à jour / supprimer, mais pas encore valider. puis dans l'autre fenêtre, vous pouvez voir à quoi ressemble la base de données de l'extérieur de la transaction. En fonction du niveau d'isolement, la table peut être verrouillée jusqu'à ce que la première fenêtre soit validée, ou vous pouvez (ne pas) voir ce que l'autre transaction a fait jusqu'à présent, etc.

Jouez avec les différents niveaux d'isolation et sans indice de verrouillage pour voir comment ils affectent les résultats.

Voir également ce qui se passe lorsque vous lancez une erreur dans la transaction.

Il est très important de comprendre comment tout cela fonctionne ou vous serez déconcerté par ce que fait sql, plusieurs fois.

S'amuser! GJ.

gjvdkamp
la source
ok mais la transaction sera-t-elle écrite pour se connecter au moins avant d'émettre le commit? Par exemple, disons que je veux démarrer une transaction, exécuter une commande d'insertion et "faire autre chose" avant d'exécuter la validation. ma commande d'insertion sera-t-elle écrite dans le journal? de cette façon, si le serveur tombe en panne avant d'exécuter commit..il peut revenir là où il était et je peux simplement lancer un commit plus tard (chaque fois que j'ai fini de faire "autre chose").
user1870400
16

Les transactions sont destinées à s'exécuter complètement ou pas du tout. La seule façon de terminer une transaction est de valider, toute autre méthode entraînera une annulation.

Par conséquent, si vous commencez et que vous ne vous engagez pas, il sera annulé à la fermeture de la connexion (car la transaction a été interrompue sans être marquée comme terminée).

Piskvor a quitté le bâtiment
la source
C'est comme ça que ça devrait être, mais ce n'est pas toujours le cas.
FalcoGer
... comme MyISAM de mySQL, qui ne prend pas en charge les transactions, bien sûr.
Piskvor a quitté le bâtiment le
3

dépend du niveau d'isolement de la transaction entrante.

Explication de l'isolement des transactions SQL

Xhalent
la source
6
Le comportement des transactions ne dépend pas du niveau d'isolement. Le nombre de verrous qu'ils pourraient causer le fait.
marc_s
Je suis presque sûr que les données pouvant être lues par une connexion dépendent certainement du niveau d'isolement. Si l'isolement est défini sur READ UNCOMMITTED, vous pouvez lire les données non encore validées et peuvent en fait être annulées à un moment donné de la piste, mais cela garantit qu'il n'y a pas de verrouillage. Si vous avez READ COMMITTED comme niveau d'isolement, vous ne pouvez pas lire les lignes non validées - le deuxième client se bloquera à moins que vous n'utilisiez SNAPSHOT.
Xhalent le
2

Lorsque vous ouvrez une transaction, rien n'est verrouillé par lui-même. Mais si vous exécutez certaines requêtes à l'intérieur de cette transaction, en fonction du niveau d'isolement, certaines lignes, tables ou pages sont verrouillées, ce qui affectera d'autres requêtes qui tentent d'y accéder à partir d'autres transactions.

trèfle rouge
la source
1

Exemple de transaction

commencer tran tt

Vos instructions SQL

si une erreur s'est produite, rollback tran tt else commit tran tt

Tant que vous n’avez pas exécuté la validation de validation, les données ne seront pas modifiées

user3386471
la source
1
Notez que la dénomination des transactions n'est pas seulement inutile dans MS SQL, elle peut donner une fausse impression de contrôle. BEGIN TRAN X ... BEGIN TRAN Y ... ROLLBACK Yne fonctionne pas, par exemple. Voir stackoverflow.com/questions/1273376/…
0

En plus des problèmes de verrouillage potentiels que vous pourriez causer, vous constaterez également que vos journaux de transactions commencent à augmenter car ils ne peuvent pas être tronqués au-delà du LSN minimum pour une transaction active et si vous utilisez l'isolement de snapshot, votre magasin de versions dans tempdb augmentera pendant raisons similaires.

Vous pouvez utiliser dbcc opentranpour voir les détails de la transaction ouverte la plus ancienne.

Martin Smith
la source
0

Toute transaction non effectuée laissera le serveur verrouillé et les autres requêtes ne s'exécuteront pas sur le serveur. Vous devez soit annuler la transaction, soit la valider. La fermeture de SSMS mettra également fin à la transaction, ce qui permettra à d'autres requêtes de s'exécuter.

Josh maure
la source
-4

Le comportement n'est pas défini, vous devez donc définir explicitement un commit ou un rollback:

http://docs.oracle.com/cd/B10500_01/java.920/a96654/basic.htm#1003303

"Si le mode de validation automatique est désactivé et que vous fermez la connexion sans valider ou annuler explicitement vos dernières modifications, une opération COMMIT implicite est exécutée."

Hsqldb effectue une restauration

con.setAutoCommit(false);
stmt.executeUpdate("insert into USER values ('" +  insertedUserId + "','Anton','Alaf')");
con.close();

le résultat est

2011-11-14 14: 20: 22,519 INFO principal [SqlAutoCommitExample: 55] [AutoCommit enabled = false] 2011-11-14 14: 20: 22 546 INFO principal [SqlAutoCommitExample: 65] [Trouvé 0 # utilisateurs dans la base de données]

Bernd Schatz
la source
2
Cela peut être vrai pour Oracle (je n'en ai aucune idée), mais l'interrogateur pose des questions sur MS-SQL
PaulG
Le premier devis s'applique au pilote JDBC, pas au serveur.
djechlin le