2009-09-16 5 views
1

J'ai un programme C# .net où je dois d'abord insérer des données dans une table en utilisant une connexion sql puis ajuster le même ensemble de données en utilisant ADO.net. Je ne suis pas sûr de savoir comment vous assurer que l'insertion via la connexion sql est terminée avant de faire les changements ado.net. Je reçois une violation de la concurrence lorsque j'essaie le code ci-dessous. Je suppose que c'est un problème de condition de course.C# .net Problèmes de simultanéité - Connexion SQL puis modifications ADO.net

Je reçois une erreur de violation d'accès concurrentiel au moment de la déclaration UpdateAll et je ne peux pas sembler travailler autour

Merci pour l'aide. Voici un exemple de code avec les modifications SQL et ado.net simplifiées de façon spectaculaire.

try 
    { 

    String deleteQuery = "DELETE FROM dbo.TABLENAME"; 

    String reportQuery = @" 

    INSERT INTO TABLENAME 
    (
    COLUMN1, 
    COLUMN2, 
    COLUMN3 
) 

    SELECT 
    COLUMN1, 
    COLUMN2, 
    COLUMN3 
    FROM OTHERTABLES 

    "; 



      SqlConnection ReportConnect = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString); 
      SqlCommand cmd = new SqlCommand(); 

      cmd.CommandType = CommandType.Text; 
      cmd.Connection = ReportConnect; 
      cmd.CommandTimeout = Convert.ToInt32(Properties.Settings.Default.ReportTimeout.ToString()); 


      ReportConnect.Open(); 

      cmd.CommandText = deleteQuery; 

      cmd.ExecuteNonQuery(); 

      cmd.CommandText = reportQuery; 

      cmd.ExecuteNonQuery(); 

      ReportConnect.Close(); 

      ReportConnect.Close(); 

     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message); 

     } 



     try 
     { 
      foreach (DataRow dr in DataSet.TABLENAME) 
      { 
      dr[0] = whatever; 
      dr[0] = 100; 
      dr[0] = 42.42; 
      } 
     } 
     catch (Exception ax) 
     { 
      MessageBox.Show(ax.Message); 
     } 
     finally 
     { 
      this.tableAdapterManager.UpdateAll(this.DataSet); 
     } 
+0

Est-ce que this.DataSet contient les mêmes valeurs de la table "TABLENAME"? –

+0

Oui. Je fais cela parce que j'ai besoin de faire des calculs financiers compliqués sur l'ensemble de données qui ne peuvent pas être effectuées en utilisant sql. J'utilise les résultats de la première partie comme une graine pour effectuer des calculs dans la deuxième partie qui sont ensuite placés dans la même table. –

Répondre

2

Le problème ici est que le "tableAdapterManager" semble être créé et ouvert avant que les modifications de données ne soient effectuées (avec la commande sql). Si vous créez le SqlDataAdapter avec l'assistant, par défaut le mode de concurrence est optimiste (donc l'instruction de mise à jour et de suppression détecte si la base de données a changé ...) et échoue avec l'exception que vous exposez.

Vous pouvez résoudre ce problème dans les fenêtres de l'assistant "Générer les instructions SQL", cliquez sur "Options avancées" et décochez l'option "Utiliser l'accès optimiste".

Vous pouvez également modifier cela à partir du fichier form.designes.cs, recherchez la commande UpdateCommand de SqlDataAdapter et assurez-vous que lors de la création de SqlParameter, la propriété DataRowVersion est définie sur "Default" ou utilisez un autre constructeur.

0

En théorie ExecuteNonQuery ne serait pas complète jusqu'à ce que le SQL avait couru, ce qui rend votre question sans objet. Si vous exécutiez délibérément de façon asynchrone, ce serait différent, mais ce n'est pas le cas. Vous devez toujours être conscient des problèmes causés par plusieurs utilisateurs simultanés, bien sûr.

+0

Je reçois une erreur de violation de la concurrence au moment de l'instruction UpdateAll et je n'arrive pas à contourner ce problème. –

Questions connexes