IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

C# et transaction SQL : Comportement inattendu


Sujet :

C#

  1. #1
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 170
    Points : 7 422
    Points
    7 422
    Billets dans le blog
    1
    Par défaut C# et transaction SQL : Comportement inattendu
    Bonjour,

    J'ai un traitement dans une boucle qui fait :
    - Une insertion
    - Une selection sur les données insérées

    Etant donné que je peux avoir pas mal d'itérations dans ma boucle, j'utilise deux objets SqlCommand différents, afin de ne pas devoir recréer mes paramètres à chaque itération inutilement.

    J'ai besoin d'une transaction qui porte sur l'ensemble de la boucle.

    J'ai donc procédé comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
                        using (SqlConnection cnx = new SqlConnection(@"Server=.\SQLEXPRESS;Database=MagicGED;Trusted_Connection=True;"))
                        {
                            cnx.Open();
                            using (SqlTransaction trans = cnx.BeginTransaction())
                            {
                                using (SqlCommand cmdIns = cnx.CreateCommand())
                                {
                                    cmdIns.Transaction = trans;
                                    cmdIns.CommandText = "insert into document (id, title, extension, doc) output inserted.id values (default, @title, @extension, 0x0)";
                                    SqlParameter pTitle = cmdIns.CreateParameter();
                                    pTitle.ParameterName = "title";
                                    pTitle.SqlDbType = SqlDbType.NVarChar;
                                    pTitle.Size = 256;
                                    cmdIns.Parameters.Add(pTitle);
                                    SqlParameter pExtension = cmdIns.CreateParameter();
                                    pExtension.ParameterName = "extension";
                                    pExtension.SqlDbType = SqlDbType.NVarChar;
                                    pExtension.Size = 10;
                                    cmdIns.Parameters.Add(pExtension);
     
                                    using (SqlCommand cmdSel = cnx.CreateCommand())
                                    {
                                        cmdSel.Transaction = trans;
                                        cmdSel.CommandText = "select doc.PathName(), GET_FILESTREAM_TRANSACTION_CONTEXT() from document where id = @id";
                                        SqlParameter pId = cmdSel.CreateParameter();
                                        pId.ParameterName = "id";
                                        pId.SqlDbType = SqlDbType.UniqueIdentifier;
                                        cmdSel.Parameters.Add(pId);
     
                                        DirectoryInfo di = new DirectoryInfo(fbd.SelectedPath);
                                        FileInfo[] files = di.GetFiles("*.*", SearchOption.AllDirectories);
     
                                        toolStripProgressBar1.Value = 0;
                                        toolStripProgressBar1.Minimum = 0;
                                        toolStripProgressBar1.Maximum = files.Length;
                                        toolStripProgressBar1.Visible = true;
     
                                        foreach (FileInfo fsi in files)
                                        {
                                            bool ignore = true;
                                            for (int i = 0, len = ACCEPT_EXTENSIONS.Length; i < len; i++)
                                            {
                                                if (ACCEPT_EXTENSIONS[i] == fsi.Extension.ToLower())
                                                {
                                                    ignore = false;
                                                    break;
                                                }
                                            }
     
                                            if (!ignore)
                                            {
                                                pTitle.Value = fsi.Name;
                                                pExtension.Value = fsi.Extension.ToLower();
                                                pId.Value = cmdIns.ExecuteScalar();
     
                                                using (SqlDataReader dr = cmdSel.ExecuteReader(CommandBehavior.SingleResult | CommandBehavior.SingleRow | CommandBehavior.SequentialAccess))
                                                {
                                                    string path = dr.GetString(0);
                                                    byte[] tc = dr.GetSqlBytes(1).Buffer;
     
                                                    byte[] b = new byte[1048576];
     
                                                    using (SqlFileStream sfs = new SqlFileStream(path, tc, FileAccess.Write, FileOptions.SequentialScan, 0))
                                                    {
                                                        using (FileStream fs = new FileStream(fsi.FullName, FileMode.Open, FileAccess.Read, FileShare.Read))
                                                        {
                                                            int i = 0, l = 0;
     
                                                            while ((l = fs.Read(b, 0, b.Length)) > 0)
                                                            {
                                                                sfs.Write(b, 0, l);
                                                                i += l;
                                                            }
     
                                                            fs.Close();
                                                        }
                                                        sfs.Close();
                                                    }
                                                }
     
                                            }
                                            toolStripProgressBar1.Value++;
                                            statusStrip1.Refresh();
                                        }
                                    }
                                }
                                trans.Commit();
                            }
                            cnx.Close();
                        }
    J'affecte ma transaction à mes deux SqlCommand.

    Et là, c'est le drame : l'insertion passe, mais impossible de relire la donnée lue avec le second SqlCommand.

    Suis-je obligé d'utiliser un seul objet SqlCommand ?

    J'utilise pourtant le même SqlTransaction pour les deux SqlCommand.

    Comment faire ? J'ai tenté différents modes d'isolation de transaction, mais aucun ne semble résoudre le problème. De plus, je ne voudrais pas non plus faire n'importe quoi dans ma transaction...

  2. #2
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 170
    Points : 7 422
    Points
    7 422
    Billets dans le blog
    1
    Par défaut
    Hmpf...

    Désolé, ça marche très bien... quand on n'oublie pas de faire l'ouverture du SqlDataReader avant de lire dedans...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
                        using (SqlConnection cnx = new SqlConnection(@"Server=.\SQLEXPRESS;Database=MagicGED;Trusted_Connection=True;"))
                        {
                            cnx.Open();
                            using (SqlTransaction trans = cnx.BeginTransaction(IsolationLevel.ReadCommitted))
                            {
                                using (SqlCommand cmdIns = cnx.CreateCommand())
                                {
                                    cmdIns.Transaction = trans;
                                    cmdIns.CommandText = "insert into document (id, title, extension, doc) output inserted.id values (default, @title, @extension, 0x0)";
                                    SqlParameter pTitle = cmdIns.CreateParameter();
                                    pTitle.ParameterName = "title";
                                    pTitle.SqlDbType = SqlDbType.NVarChar;
                                    pTitle.Size = 256;
                                    cmdIns.Parameters.Add(pTitle);
                                    SqlParameter pExtension = cmdIns.CreateParameter();
                                    pExtension.ParameterName = "extension";
                                    pExtension.SqlDbType = SqlDbType.NVarChar;
                                    pExtension.Size = 10;
                                    cmdIns.Parameters.Add(pExtension);
     
                                    using (SqlCommand cmdSel = cnx.CreateCommand())
                                    {
                                        cmdSel.Transaction = trans;
                                        cmdSel.CommandText = "select doc.PathName(), GET_FILESTREAM_TRANSACTION_CONTEXT() from document where id = @id";
                                        SqlParameter pId = cmdSel.CreateParameter();
                                        pId.ParameterName = "id";
                                        pId.SqlDbType = SqlDbType.UniqueIdentifier;
                                        cmdSel.Parameters.Add(pId);
     
                                        DirectoryInfo di = new DirectoryInfo(fbd.SelectedPath);
                                        FileInfo[] files = di.GetFiles("*.*", SearchOption.AllDirectories);
     
                                        toolStripProgressBar1.Value = 0;
                                        toolStripProgressBar1.Minimum = 0;
                                        toolStripProgressBar1.Maximum = files.Length;
                                        toolStripProgressBar1.Visible = true;
     
                                        foreach (FileInfo fsi in files)
                                        {
                                            bool ignore = true;
                                            for (int i = 0, len = ACCEPT_EXTENSIONS.Length; i < len; i++)
                                            {
                                                if (ACCEPT_EXTENSIONS[i] == fsi.Extension.ToLower())
                                                {
                                                    ignore = false;
                                                    break;
                                                }
                                            }
     
                                            if (!ignore)
                                            {
                                                pTitle.Value = fsi.Name;
                                                pExtension.Value = fsi.Extension.ToLower();
                                                pId.Value = cmdIns.ExecuteScalar();
     
                                                using (SqlDataReader dr = cmdSel.ExecuteReader(CommandBehavior.SingleResult | CommandBehavior.SingleRow | CommandBehavior.SequentialAccess))
                                                {
                                                    dr.Read();
                                                    string path = dr.GetString(0);
                                                    byte[] tc = dr.GetSqlBytes(1).Buffer;
     
                                                    byte[] b = new byte[1048576];
     
                                                    using (SqlFileStream sfs = new SqlFileStream(path, tc, FileAccess.Write, FileOptions.SequentialScan, 0))
                                                    {
                                                        using (FileStream fs = new FileStream(fsi.FullName, FileMode.Open, FileAccess.Read, FileShare.Read))
                                                        {
                                                            int i = 0, l = 0;
     
                                                            while ((l = fs.Read(b, 0, b.Length)) > 0)
                                                            {
                                                                sfs.Write(b, 0, l);
                                                                i += l;
                                                            }
     
                                                            fs.Close();
                                                        }
                                                        sfs.Close();
                                                    }
                                                }
     
                                            }
                                            toolStripProgressBar1.Value++;
                                            statusStrip1.Refresh();
                                        }
                                    }
                                }
                                trans.Commit();
                            }
                            cnx.Close();
                        }

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [PL/SQL][Oracle9] Proc. Stoc. comportement inattendue
    Par Carlito_superheros dans le forum Oracle
    Réponses: 2
    Dernier message: 30/08/2006, 16h13
  2. [JDBC][Access] Transaction SQL sur MS Access?
    Par Twofy dans le forum JDBC
    Réponses: 2
    Dernier message: 19/08/2004, 14h46
  3. Transact Sql : Conversion de variable
    Par lord_paco dans le forum Langage SQL
    Réponses: 2
    Dernier message: 13/08/2003, 13h25
  4. Conversion de SQL à Transact-SQL
    Par sebioni dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 03/07/2003, 11h59
  5. - fonction Transact-SQL...
    Par korrigann dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 22/05/2003, 15h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo