1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
| using System;
using System.Data;
using System.Data.Sql;
using System.Data.SqlClient;
namespace TestNestedTransaction
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Simulation de transactions imbriquée (B imbriquée dans A)");
Console.WriteLine("On utilise donc la notion de Save Point");
using (SqlConnection cnx = new SqlConnection("Server=localhost\\SQLEXPRESS;Database=testlock;Trusted_Connection=True;"))
{
cnx.Open();
Console.WriteLine();
Console.WriteLine("Cas 1 :");
Console.WriteLine("- La transaction A est rollbackée");
Console.WriteLine("- La transaction B est committée");
Console.WriteLine("Avec une transaction imbriquée, on s'attend à ce que tout soit rollbacké");
MonObj obj1 = new MonObj(cnx);
using (SqlTransaction tran = cnx.BeginTransaction(IsolationLevel.ReadCommitted, "TransactionA"))
{
obj1.MethodA(tran, "Cas 1, transaction A");
tran.Save("Après MethodA");
obj1.MethodB(tran, "Cas 1, transaction B");
tran.Rollback();
}
Console.WriteLine();
Console.WriteLine("Cas 2 :");
Console.WriteLine("- La transaction A est committée");
Console.WriteLine("- La transaction B est rollbackée");
Console.WriteLine("Avec une transaction imbriquée, on s'attend à ce que B soit rollbackée, mais que A soit committée");
MonObj obj2 = new MonObj(cnx);
using (SqlTransaction tran = cnx.BeginTransaction(IsolationLevel.ReadCommitted, "TransactionA"))
{
obj2.MethodA(tran, "Cas 2, transaction A");
tran.Save("Après MethodA");
obj2.MethodB(tran, "Cas 2, transaction B");
tran.Rollback("Après MethodA");
tran.Commit();
}
Console.WriteLine();
Console.WriteLine("Cas 3 :");
Console.WriteLine("- La transaction A est committée");
Console.WriteLine("- La transaction B est committée");
Console.WriteLine("Avec une transaction imbriquée, on s'attend à ce que les deux transactions soient committées");
MonObj obj3 = new MonObj(cnx);
using (SqlTransaction tran = cnx.BeginTransaction(IsolationLevel.ReadCommitted, "TransactionA"))
{
obj3.MethodA(tran, "Cas 3, transaction A");
tran.Save("Après MethodA");
obj3.MethodB(tran, "Cas 3, transaction B");
tran.Commit();
}
Console.WriteLine();
Console.WriteLine("Cas 4 :");
Console.WriteLine("- La transaction A est rollbackée");
Console.WriteLine("- La transaction B est rollbackée");
Console.WriteLine("Avec une transaction imbriquée, on s'attend à ce que les deux transactions soient rollbackées");
MonObj obj4 = new MonObj(cnx);
using (SqlTransaction tran = cnx.BeginTransaction(IsolationLevel.ReadCommitted, "TransactionA"))
{
obj4.MethodA(tran, "Cas 4, transaction A");
tran.Save("Après MethodA");
obj4.MethodB(tran, "Cas 4, transaction B");
tran.Rollback("Après MethodA");
tran.Rollback();
}
Console.WriteLine();
Console.WriteLine("Résultat :");
using (SqlCommand cmd = cnx.CreateCommand())
{
cmd.CommandText = "select id, name from test order by id";
SqlDataReader da = cmd.ExecuteReader();
while (da.Read())
{
Console.WriteLine("{0}\t{1}", da.GetInt32(0), da.GetString(1));
}
}
cnx.Close();
}
Console.WriteLine();
Console.WriteLine("Fin");
Console.ReadKey(true);
}
}
class MonObj
{
SqlConnection _c;
public MonObj(SqlConnection c)
{
_c = c;
}
public void MethodA(SqlTransaction tran, string name)
{
using (SqlCommand cmd = _c.CreateCommand())
{
cmd.Transaction = tran;
cmd.CommandText = "insert into test (name) values (@name)";
cmd.Parameters.Add("name", SqlDbType.VarChar, 50).Value = name;
cmd.ExecuteNonQuery();
}
}
public void MethodB(SqlTransaction tran, string name)
{
using (SqlCommand cmd = _c.CreateCommand())
{
cmd.Transaction = tran;
cmd.CommandText = "insert into test (name) values (@name)";
cmd.Parameters.Add("name", SqlDbType.VarChar, 50).Value = name;
cmd.ExecuteNonQuery();
}
}
}
} |