TransactionScope et niveau d'isolement
nous avons un problème pour utiliser TransactionScope. TransactionScope obtenir de nous une très bonne flexibilité pour l'utilisation de transactions à l'échelle de notre Couche d'Accès aux Données. Sur cette façon, nous pouvons utiliser les transactions implicites ou explicites. Il y a quelques boost de performance encore ADO.NET les transactions, mais en ce moment ce n'est pas vraiment le problème. Cependant, nous avons problème de verrouillage. Dans l'exemple de code ci-dessous, bien que le niveau d'isolation est défini à ReadCommitted, il n'est pas possible de Sélectionner instruction SQL à partir d'un autre client sur la table testTable, jusqu'à ce que l'opération principale (dans la méthode main) sera engagé, parce qu'il y a de verrouillage sur l'ensemble de la table. Nous avons également essayé d'utiliser une seule connexion à travers toutes les méthodes, mais même comportement. Notre SGBD SQL Server 2008. Est-il quelque chose de ce que nous n'avons pas compris?
Ce qui concerne
Anton Kalcik
Voir cet exemple de code:
class Program
{
public class DAL
{
private const string _connectionString = @"Data Source=localhost\fsdf;Initial Catalog=fasdfsa;Integrated Security=SSPI;";
private const string inserttStr = @"INSERT INTO dbo.testTable (test) VALUES(@test);";
/// <summary>
/// Execute command on DBMS.
/// </summary>
/// <param name="command">Command to execute.</param>
private void ExecuteNonQuery(IDbCommand command)
{
if (command == null)
throw new ArgumentNullException("Parameter 'command' can't be null!");
using (IDbConnection connection = new SqlConnection(_connectionString))
{
command.Connection = connection;
connection.Open();
command.ExecuteNonQuery();
}
}
public void FirstMethod()
{
IDbCommand command = new SqlCommand(inserttStr);
command.Parameters.Add(new SqlParameter("@test", "Hello1"));
using (TransactionScope sc = new TransactionScope(TransactionScopeOption.Required))
{
ExecuteNonQuery(command);
sc.Complete();
}
}
public void SecondMethod()
{
IDbCommand command = new SqlCommand(inserttStr);
command.Parameters.Add(new SqlParameter("@test", "Hello2"));
using (TransactionScope sc = new TransactionScope(TransactionScopeOption.Required))
{
ExecuteNonQuery(command);
sc.Complete();
}
}
}
static void Main(string[] args)
{
DAL dal = new DAL();
TransactionOptions tso = new TransactionOptions();
tso.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
using (TransactionScope sc = new TransactionScope(TransactionScopeOption.Required,tso))
{
dal.FirstMethod();
dal.SecondMethod();
sc.Complete();
}
}
}
source d'informationauteur Anton Kalcik
Vous devez vous connecter pour publier un commentaire.
Je ne pense pas que votre problème n'a rien à voir avec l' .NET TransactionScope concept. Plutôt, il semble que vous êtes décrivant le comportement attendu de SQL Server transactions. Aussi, en changeant le niveau d'isolement affecte uniquement les données "lit" pas de données "écrit". À partir de SQL Server BOL:
Ce que cela signifie est que vous pouvez empêcher le blocage de comportement en changeant le niveau d'isolation pour le client l'émission de la
SELECT
déclaration(s). LeREAD COMMITED
niveau d'isolation (valeur par défaut) ne l'empêchera pas de blocage. Pour éviter de bloquer le client, vous devez utiliser laREAD UNCOMMITTED
niveau d'isolation, mais vous devez tenir compte de la possibilité que les enregistrements peuvent être récupérés qui ont été mis à jour, inséré par une transaction ouverte (c'est à dire qu'ils peuvent disparaître si la transaction est annulée).Bonne question à parler de transactions.
Votre méthode principale est de maintenir les opérations à engager. Même si vous vous engagez dans d'autres méthodes, vous aurez toujours des verrous sur cette ligne. Vous ne serez pas en mesure de lire la table de LECTURE COMMIS, ce qui est prévu, jusqu'à ce que vous livrez votre verrouillage de la transaction.
Ici est d'après la première méthode retourne:
Après la deuxième méthode retourne, vous allez ajouter un plus de verrouillage de la table.
Si on exécute l'instruction select à partir d'une fenêtre de requête avec SPID(55), vous verrez le statut en attente.
Après la méthode principale de trans s'engage, vous obtiendrez les résultats d'instruction select et il n'affiche que les partagé de serrure de notre instruction select de la requête de la page.
X moyens de verrouillage exclusif, IX intention de serrures. Vous pouvez en lire plus à partir de mon blog sur les transactions.
Si vous voulez le lire sans attendre, vous pouvez utiliser l'indicateur nolock. Si vous voulez lire d'après la première méthode valide, vous pouvez le retirer extérieur de la portée.