Results 1 to 1 of 1

Thread: Concurrency Error when record is deleted by another user

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Jun 2012
    Location
    Minnesota
    Posts
    238

    Concurrency Error when record is deleted by another user

    Ok I have been trying to handle some of the concurrency errors on my winforms app. When the database record has changed and the user tries to save it gives a popup with a choice to overwrite or cancel basically.

    My problem is if the record was deleted by another user and they try to save changes to it I get this error...
    Name:  nullexception.JPG
Views: 738
Size:  47.0 KB

    This is what I have for my saving code right now. In the Save() function I tried to catch that NullException and just tell the user that record has already been deleted by another user, but it doesn't work.

    I have a save button that runs this code...
    Code:
      Private Sub PordersBindingNavigatorSaveItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PordersBindingNavigatorSaveItem.Click
            Me.Validate()
            Me.PordersBindingSource.EndEdit()
            Me.ItemsBindingSource.EndEdit()
            Me.PoinvoiceBindingSource.EndEdit()
            If Me.Save() Then
                MsgBox("Your purchase order changes were saved.")
            End If
    
        End Sub
    Then the Save() Function that runs this code...
    Code:
       Private Function Save() As Boolean
            Dim saved As Boolean = False
    
            If Me.PordersItemsDataSet.HasChanges Then
                Try
    
                    Dim pordersUpdates() As DataRow = Me.PordersItemsDataSet.porders.Select("", "", DataViewRowState.Added Or DataViewRowState.ModifiedCurrent)
                    Dim itemsUpdates() As DataRow = Me.PordersItemsDataSet.items.Select("", "", DataViewRowState.Added Or DataViewRowState.ModifiedCurrent)
                    Dim invoiceUpdates() As DataRow = Me.PordersItemsDataSet.poinvoice.Select("", "", DataViewRowState.Added Or DataViewRowState.ModifiedCurrent)
    
                    UpdateDatabasePorders()       ' Me.PordersTableAdapter.Update(pordersUpdates)
                    UpdateDatabaseItems()         ' Me.ItemsTableAdapter.Update(itemsUpdates)
                    UpdateDatabaseInvoice()       ' Me.PoinvoiceTableAdapter.Update(invoiceUpdates)
    
                    Dim pordersDeletes() As DataRow = Me.PordersItemsDataSet.porders.Select("", "", DataViewRowState.Deleted)
                    Dim itemsDeletes() As DataRow = Me.PordersItemsDataSet.items.Select("", "", DataViewRowState.Deleted)
                    Dim invoiceDeletes() As DataRow = Me.PordersItemsDataSet.poinvoice.Select("", "", DataViewRowState.Deleted)
    
                    Try
                        Me.PoinvoiceTableAdapter.Update(invoiceDeletes)
                    Catch dbcx As System.NullReferenceException
                        MsgBox("This record has already been deleted by another user.")
                    Catch ex As Exception
                        MsgBox("An error was thrown while attempting to update the Invoice Table.")
                    End Try                Me.ItemsTableAdapter.Update(itemsDeletes)
                    Me.PordersTableAdapter.Update(pordersDeletes)
    
                    saved = True
    
                Catch ex As Exception
                    MsgBox(ex.ToString)
                End Try
            End If
    
            Return saved
    
        End Function
    These subs are for when it runs the UpdateDatabasePorders. They look basically the same for UpdateDatabaseItems and UpdateDatabaseInvoice.
    Code:
        Private Sub UpdateDatabasePorders()
            Try
                Me.PordersTableAdapter.Update(Me.PordersItemsDataSet.porders)
                'MsgBox("Update successful on Purchase Orders Table")
    
            Catch dbdel As System.NullReferenceException
                MsgBox("This record was deleted by another user.")
    
            Catch dbcx As Data.DBConcurrencyException
                Dim response As Windows.Forms.DialogResult
    
                response = MessageBox.Show(CreateMessagePorders(CType(dbcx.Row, PordersItemsDataSet.pordersRow)),
                    "Concurrency Exception", MessageBoxButtons.YesNo)
    
                ProcessDialogResultPorders(response)
    
            Catch ex As Exception
                MsgBox("An error was thrown while attempting to update the Purchase Orders Table.")
            End Try
        End Sub
    
        Private Function CreateMessagePorders(ByVal crp As PordersItemsDataSet.pordersRow) As String
            Return "Database: " & GetRowDataPorders(GetCurrentRowInDBPorders(crp),
                                             Data.DataRowVersion.Default) & vbCrLf &
                   "Original: " & GetRowDataPorders(crp, Data.DataRowVersion.Original) & vbCrLf &
                   "Proposed: " & GetRowDataPorders(crp, Data.DataRowVersion.Current) & vbCrLf &
                   "Do you still want to update the database with the proposed value?"
        End Function
    
    
        '--------------------------------------------------------------------------
        ' This method loads a temporary table with current records from the database
        ' and returns the current values from the row that caused the exception.
        '--------------------------------------------------------------------------
        Private TempPordersDataTable As New PordersItemsDataSet.pordersDataTable
    
        Private Function GetCurrentRowInDBPorders(
            ByVal RowWithError As PordersItemsDataSet.pordersRow
            ) As PordersItemsDataSet.pordersRow
    
            Me.PordersTableAdapter.Fill(TempPordersDataTable)
    
            Dim currentRowInDbPorders As PordersItemsDataSet.pordersRow =
                TempPordersDataTable.FindByPONum(RowWithError.PONum)
    
            Return currentRowInDbPorders
        End Function
    
    
        '--------------------------------------------------------------------------
        ' This method takes a pordersRow and RowVersion 
        ' and returns a string of column values to display to the user.
        '--------------------------------------------------------------------------
        Private Function GetRowDataPorders(ByVal custRow As PordersItemsDataSet.pordersRow,
            ByVal RowVersion As Data.DataRowVersion) As String
    
            Dim rowData As String = ""
    
            For i As Integer = 0 To custRow.ItemArray.Length - 1
                rowData &= custRow.Item(i, RowVersion).ToString() & " "
            Next
    
            Return rowData
        End Function
    
        Private Sub ProcessDialogResultPorders(ByVal response As Windows.Forms.DialogResult)
            Select Case response
    
                Case Windows.Forms.DialogResult.Yes
                    PordersItemsDataSet.porders.Merge(TempPordersDataTable, True)
                    UpdateDatabasePorders()
    
                Case Windows.Forms.DialogResult.No
                    PordersItemsDataSet.porders.Merge(TempPordersDataTable)
                    MsgBox("Update cancelled for Purchase Orders Table")
            End Select
        End Sub
    Anyone have any idea how to handle the concurrency problem when the record is deleted by one user but still visible to another user until they refresh?

    Thanks,
    Stacy
    Last edited by StacyOW; Nov 2nd, 2013 at 07:00 PM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width