none
Ayuda con consultas distribuidas RRS feed

  • Pregunta

  • Hola he estado intentando actualizar dos BD al mismo tiempo, las BD son como decir replicadas.
    ME han puesto hacer un trabajo, y debo abrir una BD por ej en un datagridview modificar la info y que esos cambios queden guardados en ambas tablas. Lo q he hecho es crear las conexiones a las dos bd. Y actualizar por el commadbuilder, pero no he logrado
    El codigo es
    Lo qye hago es llamar al rootMethod.
    En este metodo actualizo la BD que esta abierta en el datagridView, y en el otro metodo, actualizo la segunda BD q es la q nunca muestro
    PEro esta no se me actualiza, pq?
    Gracias
        void RootMethod()
            {
                TransactionOptions options = new TransactionOptions();
                options.IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted;
                using (TransactionScope scope = new TransactionScope())
                {
                    try
                    {
                        cb = new SqlCommandBuilder(da);
                        da.UpdateCommand = cb.GetUpdateCommand();
                        d = ((DataTable)dataGridView1.DataSource);
                        da.Update((DataTable)dataGridView1.DataSource);
                        cnn.ChangeDatabase("Gasolinera");
                        
                        //cnn.ChangeDatabase("Gasolinera1");
                    }
                    catch (Exception er)
                    {
                        MessageBox.Show("Error de formato" + er.Message);
                    }
    
                    SomeMethod();
                    scope.Complete();
                }
            }
    
            void SomeMethod()
            {
                using (TransactionScope scope = new TransactionScope())
                {
                    try
                    {
                        cb = new SqlCommandBuilder(da);
                        da.AcceptChangesDuringFill = true;
                        da.UpdateCommand = cb.GetUpdateCommand();
                        da.DeleteCommand = cb.GetDeleteCommand();
                        
                        da.InsertCommand = cb.GetInsertCommand();
                        da.Update((DataTable)dataGridView1.DataSource);
                        
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Error de formato" + ex.Message);
                        
                    }
                    /* Perform transactional work here */
                    scope.Complete();
                }
            }
    
    • Cambiado Gustavo Larriera jueves, 19 de noviembre de 2009 14:45 +Adecuado. (De:SQL Server)
    martes, 17 de noviembre de 2009 3:56

Respuestas

  • Hola.

    Este foro es de SQL Server, y este problema no parece de SQL Server, sino de C#. Aún así, no logro ver dónde están las dos conexiones (una a cada base de datos) ni la sentencia que ha de ejecutarse, ni siquiera la transacción distribuida o las dos transacciones que han de iniciarse y completarse para que se graben los datos. Tampoco hay ningún mensaje de error que podamos interpretar. No sé si todo eso que no veo está en partes que no has enviado.

    Una cosa que se me ocurre es que introduzcas líneas de código que te permitan asegurarte de que estás intentando actualizar la base de datos adecuada en cada momento, algo así como que te saque un MessageBox con la cadena de conexión justo antes de grabar, porque lo que parece que te ocurre es que estás actualizando las dos veces en la misma base de datos.


    Alberto López Grande (Visita mi blog en http://qwalgrande.blogspot.es/)
    • Marcado como respuesta Rafael Fagundes jueves, 19 de noviembre de 2009 13:48
    martes, 17 de noviembre de 2009 7:50
  • Probablemente sería mejor que hicieses la pregunta en el grupo de ADO.NET: http://social.msdn.microsoft.com/Forums/es-ES/netfxes/threads

    En cualquier caso, aunque tu código en principio debería funcionar, veo algunas cosillas raras:

    - No estás haciendo una transacción distribuida, sino dos transacciones separadas, ya que estás anidando un TransactionScope dentro de otro. Para tu ejemplo, el segundo transactionScope que tienes dentro del SomeMethd sobraría, ya que estás llamando a este método mientras todavía está abierto el primer TransactionScope.

    - Puesto que puedes acceder a la segunda base de datos haciendo un "ChangeDatabase", no hay ninguna necesidad de una transacción distribuida. Bastaría con una transacción local usando el BeginTransaction en lugar del TransactionScope. No obstante, en teoría el TransactionScope es lo bastante inteligente para inicial la transacción como local, y sólo escalarla a distribuida cuando abres una segunda conexión a otro servidor.

    - Estás conectando DOS SqlCommandBuilders al mismo SqlDataAdapter da. Y luego haces varias manipulaciones innecesarias tales como da.UpdateCommand = cb.GetUpdateCommand();. Esto es superfluo, al conectar el CommandBuilder con el DataAdapter en el constructor ya se asignan todos los Commands del DataAdapter. Y una vez asignados, los conserva, así que es superfluo asignarlos en el método principal y luego volver a poner otro CommandBuilder en el SomeMethod.

    Por lo demás, el código debería funcionar. Te sugeriría (ya que estamos en un foro de Sql Server) usar el Sql Server Profiler para capturar las sentencias que está mandando tu programa al servidor, y ver qué es lo que realmente se está generando. Esto te debería dar una pista muy importante acerca de qué es lo que puede estar fallando en el código fuente.
    • Marcado como respuesta Rafael Fagundes jueves, 19 de noviembre de 2009 13:48
    martes, 17 de noviembre de 2009 8:19

Todas las respuestas

  • Hola.

    Este foro es de SQL Server, y este problema no parece de SQL Server, sino de C#. Aún así, no logro ver dónde están las dos conexiones (una a cada base de datos) ni la sentencia que ha de ejecutarse, ni siquiera la transacción distribuida o las dos transacciones que han de iniciarse y completarse para que se graben los datos. Tampoco hay ningún mensaje de error que podamos interpretar. No sé si todo eso que no veo está en partes que no has enviado.

    Una cosa que se me ocurre es que introduzcas líneas de código que te permitan asegurarte de que estás intentando actualizar la base de datos adecuada en cada momento, algo así como que te saque un MessageBox con la cadena de conexión justo antes de grabar, porque lo que parece que te ocurre es que estás actualizando las dos veces en la misma base de datos.


    Alberto López Grande (Visita mi blog en http://qwalgrande.blogspot.es/)
    • Marcado como respuesta Rafael Fagundes jueves, 19 de noviembre de 2009 13:48
    martes, 17 de noviembre de 2009 7:50
  • Probablemente sería mejor que hicieses la pregunta en el grupo de ADO.NET: http://social.msdn.microsoft.com/Forums/es-ES/netfxes/threads

    En cualquier caso, aunque tu código en principio debería funcionar, veo algunas cosillas raras:

    - No estás haciendo una transacción distribuida, sino dos transacciones separadas, ya que estás anidando un TransactionScope dentro de otro. Para tu ejemplo, el segundo transactionScope que tienes dentro del SomeMethd sobraría, ya que estás llamando a este método mientras todavía está abierto el primer TransactionScope.

    - Puesto que puedes acceder a la segunda base de datos haciendo un "ChangeDatabase", no hay ninguna necesidad de una transacción distribuida. Bastaría con una transacción local usando el BeginTransaction en lugar del TransactionScope. No obstante, en teoría el TransactionScope es lo bastante inteligente para inicial la transacción como local, y sólo escalarla a distribuida cuando abres una segunda conexión a otro servidor.

    - Estás conectando DOS SqlCommandBuilders al mismo SqlDataAdapter da. Y luego haces varias manipulaciones innecesarias tales como da.UpdateCommand = cb.GetUpdateCommand();. Esto es superfluo, al conectar el CommandBuilder con el DataAdapter en el constructor ya se asignan todos los Commands del DataAdapter. Y una vez asignados, los conserva, así que es superfluo asignarlos en el método principal y luego volver a poner otro CommandBuilder en el SomeMethod.

    Por lo demás, el código debería funcionar. Te sugeriría (ya que estamos en un foro de Sql Server) usar el Sql Server Profiler para capturar las sentencias que está mandando tu programa al servidor, y ver qué es lo que realmente se está generando. Esto te debería dar una pista muy importante acerca de qué es lo que puede estar fallando en el código fuente.
    • Marcado como respuesta Rafael Fagundes jueves, 19 de noviembre de 2009 13:48
    martes, 17 de noviembre de 2009 8:19