Tratar las excepciones de simultaneidadHandle a concurrency exception

Las excepciones de simultaneidad (System.Data.DBConcurrencyException) se producen cuando dos usuarios intentan cambiar los mismos datos al mismo tiempo en una base de datos.Concurrency exceptions (System.Data.DBConcurrencyException) are raised when two users attempt to change the same data in a database at the same time. En este tutorial, creará una aplicación de Windows que ilustra cómo detectar una DBConcurrencyException, busque la fila que produjo el error y obtenga información sobre una estrategia para saber cómo controlarla.In this walkthrough, you create a Windows application that illustrates how to catch a DBConcurrencyException, locate the row that caused the error, and learn a strategy for how to handle it.

Este tutorial le guía a través del proceso siguiente:This walkthrough takes you through the following process:

  1. Cree un nuevo proyecto de aplicación de Windows Forms.Create a new Windows Forms Application project.

  2. Cree un nuevo conjunto de datos basado en la tabla Customers de Northwind.Create a new dataset based on the Northwind Customers table.

  3. Crear un formulario con un control DataGridView para mostrar los datos.Create a form with a DataGridView to display the data.

  4. Rellenar un conjunto de datos con datos de la tabla Customers de la base de datos Northwind.Fill a dataset with data from the Customers table in the Northwind database.

  5. Use la mostrar datos de tabla de características en Explorador de servidores para tener acceso a datos de la tabla Customers y cambiar un registro.Use the Show Table Data feature in Server Explorer to access the Customers-table's data and change a record.

  6. Cambiar el mismo registro en un valor diferente, actualizar el conjunto de datos e intenta escribir los cambios en la base de datos, lo que resulta en que se produzca un error de simultaneidad.Change the same record to a different value, update the dataset, and attempt to write the changes to the database, which results in a concurrency error being raised.

  7. Detectar el error, mostrar las diferentes versiones del registro, que permite al usuario determinar si debe continuar y actualizar la base de datos o cancelar la actualización.Catch the error, then display the different versions of the record, allowing the user to determine whether to continue and update the database, or cancel the update.

Requisitos previosPrerequisites

En este tutorial usa SQL Server Express LocalDB y la base de datos de ejemplo Northwind.This walkthrough uses SQL Server Express LocalDB and the Northwind sample database.

  1. Si no tiene SQL Server Express LocalDB, instálelo de desde el página de descarga de SQL Server Express, o a través del instalador de Visual Studio.If you don't have SQL Server Express LocalDB, install it either from the SQL Server Express download page, or through the Visual Studio Installer. En el instalador de Visual Studio, puede instalar SQL Server Express LocalDB como parte de la procesamiento y almacenamiento de datos carga de trabajo, o como un componente individual.In the Visual Studio Installer, you can install SQL Server Express LocalDB as part of the Data storage and processing workload, or as an individual component.

  2. Instalar la base de datos de ejemplo Northwind, siga estos pasos:Install the Northwind sample database by following these steps:

    1. En Visual Studio, abra el Explorador de objetos de SQL Server ventana.In Visual Studio, open the SQL Server Object Explorer window. (Explorador de objetos de SQL Server se instala como parte de la procesamiento y almacenamiento de datos carga de trabajo en el instalador de Visual Studio.) Expanda el SQL Server nodo.(SQL Server Object Explorer is installed as part of the Data storage and processing workload in the Visual Studio Installer.) Expand the SQL Server node. Haga doble clic en la instancia de LocalDB y seleccione nueva consulta.Right-click on your LocalDB instance and select New Query.

      Se abre una ventana del editor de consultas.A query editor window opens.

    2. Copia el script Transact-SQL de Northwind en el Portapapeles.Copy the Northwind Transact-SQL script to your clipboard. Este script de Transact-SQL crea la base de datos Northwind desde el principio y lo rellena con datos.This T-SQL script creates the Northwind database from scratch and populates it with data.

    3. Pegue el script de Transact-SQL en el editor de consultas y, a continuación, elija el Execute botón.Paste the T-SQL script into the query editor, and then choose the Execute button.

      Después de un breve tiempo, finalice la consulta y se crea la base de datos Northwind.After a short time, the query finishes running and the Northwind database is created.

Note

Los cuadros de diálogo y comandos de menú que se ven pueden diferir de los descritos en la ayuda según la configuración activa o la edición que esté usando.The dialog boxes and menu commands you see might differ from those described in Help depending on your active settings or the edition that you're using. Para cambiar la configuración, elija la opción Importar y exportar configuraciones del menú Herramientas .To change your settings, choose Import and Export Settings on the Tools menu. Para más información, vea Personalizar el IDE de Visual Studio.For more information, see Personalize the Visual Studio IDE.

Crear un proyecto nuevoCreate a new project

Empiece por crear una nueva aplicación de Windows Forms:Begin by creating a new Windows Forms application:

  1. En Visual Studio, en el archivo menú, seleccione New > proyecto.In Visual Studio, on the File menu, select New > Project.

  2. Expanda el Visual C# o Visual Basic en el panel izquierdo, seleccione Windows Desktop.Expand either Visual C# or Visual Basic in the left-hand pane, then select Windows Desktop.

  3. En el panel central, seleccione la aplicación de Windows Forms tipo de proyecto.In the middle pane, select the Windows Forms App project type.

  4. Denomine el proyecto ConcurrencyWalkthroughy, a continuación, elija Aceptar.Name the project ConcurrencyWalkthrough, and then choose OK.

    El ConcurrencyWalkthrough se crea y se agrega al proyecto el Explorador de soluciones, y se abre un nuevo formulario en el diseñador.The ConcurrencyWalkthrough project is created and added to Solution Explorer, and a new form opens in the designer.

Crear el conjunto de datos NorthwindCreate the Northwind dataset

A continuación, cree un conjunto de datos denominado NorthwindDataSet:Next, create a dataset named NorthwindDataSet:

  1. En el datos menú, elija Agregar nuevo origen de datos.On the Data menu, choose Add New Data source.

    Se abre el Asistente para configuración de orígenes de datos.The Data Source Configuration Wizard opens.

  2. En el elegir un tipo de origen de datos pantalla, seleccione base de datos.On the Choose a Data Source Type screen, select Database.

    Asistente para configuración de origen de datos en Visual Studio

  3. Seleccione una conexión a la base de datos de ejemplo Northwind desde la lista de conexiones disponibles.Select a connection to the Northwind sample database from the list of available connections. Si la conexión no está disponible en la lista de conexiones, seleccione nueva conexión.If the connection is not available in the list of connections, select New Connection.

    Note

    Si se conecta a un archivo de base de datos local, seleccione No cuando se le pregunte si prefiere que desea agregar el archivo al proyecto.If you're connecting to a local database file, select No when asked if you would you like to add the file to your project.

  4. En el Guardar cadena de conexión en el archivo de configuración de aplicación pantalla, seleccione siguiente.On the Save connection string to the application configuration file screen, select Next.

  5. Expanda el tablas nodo y seleccione el clientes tabla.Expand the Tables node and select the Customers table. El nombre predeterminado del conjunto de datos debe ser NorthwindDataSet.The default name for the dataset should be NorthwindDataSet.

  6. Seleccione finalizar para agregar el conjunto de datos al proyecto.Select Finish to add the dataset to the project.

Crear un control de DataGridView enlazado a datosCreate a data-bound DataGridView control

En esta sección, creará un System.Windows.Forms.DataGridView arrastrando el clientes de elemento de la orígenes de datos ventana hasta el formulario de Windows.In this section, you create a System.Windows.Forms.DataGridView by dragging the Customers item from the Data Sources window onto your Windows Form.

  1. En el datos menú, elija Mostrar orígenes de datos para abrir el ventana Orígenes de datos.On the Data menu, choose Show Data Sources to open the Data Sources Window.

  2. En el orígenes de datos ventana, expanda el NorthwindDataSet nodo y, a continuación, seleccione el clientes tabla.In the Data Sources window, expand the NorthwindDataSet node, and then select the Customers table.

  3. Seleccione la flecha abajo en el nodo de tabla y, a continuación, seleccione DataGridView en la lista desplegable.Select the down arrow on the table node, and then select DataGridView in the drop-down list.

  4. Arrastre la tabla hasta un área vacía de su formulario.Drag the table onto an empty area of your form.

    Un DataGridView control denominado CustomersDataGridViewy un BindingNavigator denominado CustomersBindingNavigator, se agregan al formulario que está enlazado a la BindingSource.A DataGridView control named CustomersDataGridView, and a BindingNavigator named CustomersBindingNavigator, are added to the form that's bound to the BindingSource. Esto, a su vez, depende de la tabla Customers en NorthwindDataSet.This is, in turn, bound to the Customers table in the NorthwindDataSet.

Comprobar el formularioTest the form

Ahora puede probar el formulario para asegurarse de que se comporta según lo previsto hasta este punto:You can now test the form to make sure it behaves as expected up to this point:

  1. Seleccione F5 para ejecutar la aplicación.Select F5 to run the application.

    El formulario aparece con un DataGridView control en él que se rellena con datos de la tabla Customers.The form appears with a DataGridView control on it that's filled with data from the Customers table.

  2. En el depurar menú, seleccione Detener depuración.On the Debug menu, select Stop Debugging.

Controlar los errores de simultaneidadHandle concurrency errors

Cómo controlar los errores depende de las reglas de negocios específicas que rigen la aplicación.How you handle errors depends on the specific business rules that govern your application. En este tutorial, usamos la estrategia siguiente como ejemplo de cómo controlar el error de simultaneidad.For this walkthrough, we use the following strategy as an example for how to handle the concurrency error.

La aplicación presentará al usuario tres versiones del registro:The application presents the user with three versions of the record:

  • El registro actual en la base de datosThe current record in the database

  • El registro original cargado en el conjunto de datosThe original record that's loaded into the dataset

  • Los cambios propuestos en el conjunto de datosThe proposed changes in the dataset

El usuario, a continuación, es capaz de sobrescribir la base de datos con la versión propuesta, o cancelar la actualización y actualizar el conjunto de datos con los nuevos valores de la base de datos.The user is then able to either overwrite the database with the proposed version, or cancel the update and refresh the dataset with the new values from the database.

Para habilitar el control de errores de simultaneidadTo enable the handling of concurrency errors

  1. Crear un controlador de errores personalizado.Create a custom error handler.

  2. Presentar opciones al usuario.Display choices to the user.

  3. Procesar la respuesta del usuario.Process the user's response.

  4. Reenviar la actualización o reestablecer los datos en el conjunto de datos.Resend the update, or reset the data in the dataset.

Agregue código para controlar la excepción de simultaneidadAdd code to handle the concurrency exception

Cuando se intenta realizar una actualización y se produce una excepción, por lo general desea hacer algo con la información suministrada por la excepción producida.When you attempt to perform an update and an exception is raised, you generally want to do something with the information that's provided by the raised exception. En esta sección, agregue código que intenta actualizar la base de datos.In this section, you add code that attempts to update the database. El usuario controle también cualquier DBConcurrencyException que puedan generarse, así como cualquier otra excepción.You also handle any DBConcurrencyException that might be raised, as well as any other exceptions.

Note

El CreateMessage y ProcessDialogResults se agregan métodos más adelante en el tutorial.The CreateMessage and ProcessDialogResults methods are added later in the walkthrough.

  1. Agregue el código siguiente al método Form1_Load:Add the following code below the Form1_Load method:

    private void UpdateDatabase()
    {
        try
        {
            this.customersTableAdapter.Update(this.northwindDataSet.Customers);
            MessageBox.Show("Update successful");
        }
        catch (DBConcurrencyException dbcx)
        {
            DialogResult response = MessageBox.Show(CreateMessage((NorthwindDataSet.CustomersRow)
                (dbcx.Row)), "Concurrency Exception", MessageBoxButtons.YesNo);
    
            ProcessDialogResult(response);
        }
        catch (Exception ex)
        {
            MessageBox.Show("An error was thrown while attempting to update the database.");
        }
    }
    
    Private Sub UpdateDatabase()
    
        Try
            Me.CustomersTableAdapter.Update(Me.NorthwindDataSet.Customers)
            MsgBox("Update successful")
    
        Catch dbcx As Data.DBConcurrencyException
            Dim response As Windows.Forms.DialogResult
    
            response = MessageBox.Show(CreateMessage(CType(dbcx.Row, NorthwindDataSet.CustomersRow)),
                "Concurrency Exception", MessageBoxButtons.YesNo)
    
            ProcessDialogResult(response)
    
        Catch ex As Exception
            MsgBox("An error was thrown while attempting to update the database.")
        End Try
    End Sub
    
  2. Reemplace el método CustomersBindingNavigatorSaveItem_Click para llamar al método UpdateDatabase de manera que tenga el siguiente aspecto:Replace the CustomersBindingNavigatorSaveItem_Click method to call the UpdateDatabase method so it looks like the following:

    private void customersBindingNavigatorSaveItem_Click(object sender, EventArgs e)
    {
        UpdateDatabase();
    }
    
    Private Sub CustomersBindingNavigatorSaveItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CustomersBindingNavigatorSaveItem.Click
        UpdateDatabase()
    End Sub
    

Mostrar opciones al usuarioDisplay choices to the user

El código que acaba de escribir llama al procedimiento CreateMessage para mostrar información de error al usuario.The code you just wrote calls the CreateMessage procedure to display error information to the user. En este tutorial, usará un cuadro de mensaje para mostrar las diferentes versiones del registro para el usuario.For this walkthrough, you use a message box to display the different versions of the record to the user. Esto permite al usuario elegir si desea sobrescribir el registro con los cambios o cancelar la edición.This enables the user to choose whether to overwrite the record with the changes or cancel the edit. Cuando el usuario selecciona una opción (hace clic en un botón) en el cuadro de mensaje, la respuesta se pasa al método ProcessDialogResult.Once the user selects an option (clicks a button) on the message box, the response is passed to the ProcessDialogResult method.

Crear el mensaje agregando el código siguiente a la Editor de código.Create the message by adding the following code to the Code Editor. Escriba este código debajo el UpdateDatabase método:Enter this code below the UpdateDatabase method:

 [!code-csharp[VbRaddataConcurrency#4](../data-tools/codesnippet/CSharp/handle-a-concurrency-exception_3.cs)]
 [!code-vb[VbRaddataConcurrency#4](../data-tools/codesnippet/VisualBasic/handle-a-concurrency-exception_3.vb)]

Procesar la respuesta del usuarioProcess the user's response

También necesita código para procesar la respuesta del usuario en el cuadro de mensaje.You also need code to process the user's response to the message box. Las opciones son sobrescribir el registro actual en la base de datos con el cambio propuesto, o abandonar los cambios locales y actualizar la tabla de datos con el registro que está actualmente en la base de datos.The options are either to overwrite the current record in the database with the proposed change, or abandon the local changes and refresh the data table with the record that's currently in the database. Si el usuario elige , Merge se llama al método con el preserveChanges establecido en true.If the user chooses Yes, the Merge method is called with the preserveChanges argument set to true. Esto hace que el intento de actualización se realice correctamente, porque la versión original del registro ahora coincide con el registro en la base de datos.This causes the update attempt to be successful, because the original version of the record now matches the record in the database.

Agregue el código siguiente debajo del código que agregó en la sección anterior:Add the following code below the code that was added in the previous section:

 [!code-csharp[VbRaddataConcurrency#3](../data-tools/codesnippet/CSharp/handle-a-concurrency-exception_4.cs)]
 [!code-vb[VbRaddataConcurrency#3](../data-tools/codesnippet/VisualBasic/handle-a-concurrency-exception_4.vb)]

Comprobar el formularioTest the form

Puede comprobar el formulario para asegurarse de que se comporta de la forma prevista.You can now test the form to make sure it behaves as expected. Para simular una infracción de simultaneidad, cambia los datos en la base de datos después de rellenar el NorthwindDataSet.To simulate a concurrency violation, you change data in the database after filling the NorthwindDataSet.

  1. Seleccione F5 para ejecutar la aplicación.Select F5 to run the application.

  2. Después de que el formulario aparezca, ejecútelo y cambie al IDE de Visual Studio.After the form appears, leave it running and switch to the Visual Studio IDE.

  3. En el vista menú, elija Explorador de servidores.On the View menu, choose Server Explorer.

  4. En Explorador de servidores, expanda la conexión de la aplicación está utilizando y, a continuación, expanda el tablas nodo.In Server Explorer, expand the connection your application is using, and then expand the Tables node.

  5. Haga clic en el clientes de tabla y, a continuación, seleccione mostrar datos de tabla.Right-click the Customers table, and then select Show Table Data.

  6. En el primer registro (ALFKI), cambiar ContactName a Maria Anders2.In the first record (ALFKI), change ContactName to Maria Anders2.

    Note

    Navegue hasta una fila diferente para confirmar el cambio.Navigate to a different row to commit the change.

  7. Cambie al formulario ConcurrencyWalkthrough en ejecución.Switch to the ConcurrencyWalkthrough's running form.

  8. En el primer registro en el formulario (ALFKI), cambiar ContactName a Maria Anders1.In the first record on the form (ALFKI), change ContactName to Maria Anders1.

  9. Seleccione el guardar botón.Select the Save button.

    Se produce el error de simultaneidad y aparece el cuadro de mensaje.The concurrency error is raised, and the message box appears.

    Seleccionar n cancela la actualización y actualiza el conjunto de datos con los valores que están actualmente en la base de datos.Selecting No cancels the update and updates the dataset with the values that are currently in the database. Seleccionar escribe el valor propuesto para la base de datos.Selecting Yes writes the proposed value to the database.

Vea tambiénSee also