J'utilise le code suivant pour exécuter deux commandes à la fois. J'ai utilisé sqltransaction pour m'assurer que toutes les commandes étaient exécutées ou restaurées. Lorsque je lance mon programme sans "transaction", il s'exécute correctement, mais lorsque j'utilise "transaction" avec eux, l'erreur est indiquée. Mon code est comme suit;
SqlTransaction transaction = connectionsql.BeginTransaction();
try
{
SqlCommand cmd1 = new SqlCommand("select account_name from master_account where NOT account_name = 'BANK' AND NOT account_name = 'LOAN'", connectionsql);
SqlDataReader dr1 = cmd1.ExecuteReader();
while (dr1.Read())
{
comboBox1.Items.Add(dr1[0].ToString().Trim());
}
cmd1.Dispose();
dr1.Dispose();
SqlCommand cmd2 = new SqlCommand("select items from rate",connectionsql);
SqlDataReader dr2 = cmd2.ExecuteReader();
while (dr2.Read())
{
comboBox2.Items.Add(dr2[0].ToString().Trim());
}
cmd2.Dispose();
dr2.Dispose();
transaction.Commit();
dateTimePicker4.Value = dateTimePicker3.Value;
}
catch(Exception ex)
{
transaction.Rollback();
MessageBox.Show(ex.ToString());
}
et erreur:
Vous devez indiquer à vos objets SQLCommand d'utiliser la transaction:
cmd1.Transaction = transaction;
ou dans le constructeur:
SqlCommand cmd1 = new SqlCommand("select...", connectionsql, transaction);
Assurez-vous également que l’objet connectionsql est ouvert.
Mais tout ce que vous faites sont des instructions SELECT. Les transactions bénéficieraient davantage lorsque vous utilisez des actions de type INSERT, UPDATE, etc.
L'exemple suivant crée une connexion SqlConnection et une transaction SqlTransaction. Il montre également comment utiliser les méthodes BeginTransaction, Commit et Rollback. La transaction est annulée en cas d'erreur ou supprimée sans avoir été validée. La gestion des erreurs Try/Catch est utilisée pour gérer les erreurs lors de la tentative de validation ou d'annulation de la transaction.
private static void ExecuteSqlTransaction(string connectionString)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = connection.CreateCommand();
SqlTransaction transaction;
// Start a local transaction.
transaction = connection.BeginTransaction("SampleTransaction");
// Must assign both transaction object and connection
// to Command object for a pending local transaction
command.Connection = connection;
command.Transaction = transaction;
try
{
command.CommandText =
"Insert into Region (RegionID, RegionDescription) VALUES (100, 'Description')";
command.ExecuteNonQuery();
command.CommandText =
"Insert into Region (RegionID, RegionDescription) VALUES (101, 'Description')";
command.ExecuteNonQuery();
// Attempt to commit the transaction.
transaction.Commit();
Console.WriteLine("Both records are written to database.");
}
catch (Exception ex)
{
Console.WriteLine("Commit Exception Type: {0}", ex.GetType());
Console.WriteLine(" Message: {0}", ex.Message);
// Attempt to roll back the transaction.
try
{
transaction.Rollback();
}
catch (Exception ex2)
{
// This catch block will handle any errors that may have occurred
// on the server that would cause the rollback to fail, such as
// a closed connection.
Console.WriteLine("Rollback Exception Type: {0}", ex2.GetType());
Console.WriteLine(" Message: {0}", ex2.Message);
}
}
}
}
Vous pouvez créer une SqlTransaction
à partir d'une SqlConnection
.
Et utilisez-le pour créer un nombre quelconque de SqlCommands
SqlTransaction transaction = connection.BeginTransaction();
var cmd1 = new SqlCommand(command1Text, connection, transaction);
var cmd2 = new SqlCommand(command2Text, connection, transaction);
Ou
var cmd1 = new SqlCommand(command1Text, connection, connection.BeginTransaction());
var cmd2 = new SqlCommand(command2Text, connection, cmd1.Transaction);
Si l'échec des commandes jamais entraîne des modifications inattendues ne pas utiliser la transaction.
si l'échec des commandes pourrait provoquer des modifications inattendues, mettez-les dans un bloc Try/Catch et annulez l'opération dans un autre bloc Try/Catch.
Selon MSDN :
Try/Catch gestion des exceptions doit toujours être utilisé lorsque annule une transaction. Une annulation génère une
InvalidOperationException
si la connexion est terminée ou si la transaction a déjà été annulée sur le serveur.
Voici un exemple de code:
string connStr = "[connection string]";
string cmdTxt = "[t-sql command text]";
using (var conn = new SqlConnection(connStr))
{
conn.Open();
var cmd = new SqlCommand(cmdTxt, conn, conn.BeginTransaction());
try
{
cmd.ExecuteNonQuery();
//before this line, nothing has happened yet
cmd.Transaction.Commit();
}
catch(System.Exception ex)
{
//You should always use a Try/Catch for transaction's rollback
try
{
cmd.Transaction.Rollback();
}
catch(System.Exception ex2)
{
throw ex2;
}
throw ex;
}
conn.Close();
}
La transaction est annulée dans le cas où elle est supprimée avant l'appel de la validation ou de l'annulation.
Donc, vous n'avez pas à vous soucier de la fermeture de l'application.
Eh bien, je ne comprends pas pourquoi vous utilisez la transaction dans le cas où vous faites un select
.
La transaction est utile lorsque vous modifiez (ajoutez, modifiez ou supprimez) des données de la base de données.
Supprimer la transaction sauf si vous utilisez les instructions insert
, update
ou delete
Mettre à jour ou supprimer avec une transaction SQL
private void SQLTransaction() {
try {
string sConnectionString = "My Connection String";
string query = "UPDATE [dbo].[MyTable] SET ColumnName = '{0}' WHERE ID = {1}";
SqlConnection connection = new SqlConnection(sConnectionString);
SqlCommand command = connection.CreateCommand();
connection.Open();
SqlTransaction transaction = connection.BeginTransaction("");
command.Transaction = transaction;
try {
foreach(DataRow row in dt_MyData.Rows) {
command.CommandText = string.Format(query, row["ColumnName"].ToString(), row["ID"].ToString());
command.ExecuteNonQuery();
}
transaction.Commit();
} catch (Exception ex) {
transaction.Rollback();
MessageBox.Show(ex.Message, "Error");
}
} catch (Exception ex) {
MessageBox.Show("Problem connect to database.", "Error");
}
}
Tout d'abord, vous n'avez pas besoin d'une transaction, car vous interrogez simplement des instructions select. Comme elles sont toutes deux des instructions select, vous pouvez simplement les combiner en une requête séparée par un espace et utiliser Dataset pour obtenir toutes les tables extraites. C’est mieux de cette façon puisque vous n’avez effectué qu’une transaction dans la base de données, car celle-ci est coûteuse, votre code est donc plus rapide . En second lieu, vous devez utiliser une transaction; assignez simplement la transaction à SqlCommand, comme
sqlCommand.Transaction = transaction;
De plus, il suffit d'utiliser un seul SqlCommand pour ne pas en déclarer plus d'un, car les variables consomment de l'espace et nous souhaitons également améliorer l'efficacité de votre code. Pour ce faire, assignez à commandText différentes chaînes de requête et exécutez-les comme
sqlCommand.CommandText = "select * from table1";
sqlCommand.ExecuteNonQuery();
sqlCommand.CommandText = "select * from table2";
sqlCommand.ExecuteNonQuery();