2013-02-18 93 views

回答

0

有一些方法可以將記錄「鎖定」到一個用戶,但這會導致數據庫非常慢,更不用說在實際情況下它不是那麼實際。避免併發問題的更好方法是在加載gridview時捕獲原始值,並且一旦運行更新語句或刪除語句,如果原始值不匹配,則數據庫會拒絕該命令。看看我幾周前做過的這個項目的代碼。特別注意原始值的參考。

<asp:SqlDataSource ID="SqlDataSource2" runat="server" 
      ConflictDetection="CompareAllValues" 
      ConnectionString="<%$ ConnectionStrings:TechSupport_DataConnectionString %>" 
      DeleteCommand="DELETE FROM [Technicians] WHERE [TechID] = @original_TechID AND [Name] = @original_Name AND [Email] = @original_Email AND [Phone] = @original_Phone" 
      InsertCommand="INSERT INTO [Technicians] ([Name], [Email], [Phone]) VALUES (@Name, @Email, @Phone)" 
      OldValuesParameterFormatString="original_{0}" 
      SelectCommand="SELECT * FROM [Technicians] WHERE ([TechID] = @TechID)" 
      UpdateCommand="UPDATE [Technicians] SET [Name] = @Name, [Email] = @Email, [Phone] = @Phone WHERE [TechID] = @original_TechID AND [Name] = @original_Name AND [Email] = @original_Email AND [Phone] = @original_Phone"> 
      <SelectParameters> 
       <asp:ControlParameter ControlID="DropDownList1" Name="TechID" 
        PropertyName="SelectedValue" Type="Int32" /> 
      </SelectParameters> 
      <DeleteParameters> 
       <asp:Parameter Name="original_TechID" Type="Int32" /> 
       <asp:Parameter Name="original_Name" Type="String" /> 
       <asp:Parameter Name="original_Email" Type="String" /> 
       <asp:Parameter Name="original_Phone" Type="String" /> 
      </DeleteParameters> 
      <UpdateParameters> 
       <asp:Parameter Name="Name" Type="String" /> 
       <asp:Parameter Name="Email" Type="String" /> 
       <asp:Parameter Name="Phone" Type="String" /> 
       <asp:Parameter Name="original_TechID" Type="Int32" /> 
       <asp:Parameter Name="original_Name" Type="String" /> 
       <asp:Parameter Name="original_Email" Type="String" /> 
       <asp:Parameter Name="original_Phone" Type="String" /> 
      </UpdateParameters> 
      <InsertParameters> 
       <asp:Parameter Name="Name" Type="String" /> 
       <asp:Parameter Name="Email" Type="String" /> 
       <asp:Parameter Name="Phone" Type="String" /> 
      </InsertParameters> 
     </asp:SqlDataSource> 

調整SQL語句之後,那麼你只需要一些代碼來處理使用事件處理程序,如「插入項目」等任何數據庫例外請參見下面的代碼。

protected void DetailsView1_ItemUpdated(object sender, DetailsViewUpdatedEventArgs e) 
    { 
     if (e.Exception != null) 
     { 
      lblError.Text = "A database error has occurred.<br /><br />" + "Message: " + e.Exception.Message; 
      e.ExceptionHandled = true; 
      e.KeepInEditMode = true; 
     } 
     else if (e.AffectedRows == 0) 
      lblError.Text = "Another user may have updated that product." + "<br />Please try again."; 
     else 
      DetailsView1.DataBind(); 
    } 
    protected void DetailsView1_ItemDeleted(object sender, DetailsViewDeletedEventArgs e) 
    { 
     if (e.Exception != null) 
     { 
      lblError.Text = "A database error has occurred.<br /><br />" + "Message: " + e.Exception.Message; 
      e.ExceptionHandled = true; 
     } 
     else if (e.AffectedRows == 0) 
      lblError.Text = "Another user may have updated that product." + "<br />Please try again."; 
     else 
      DetailsView1.DataBind(); 
      DropDownList1.DataBind(); 
    } 
    protected void DetailsView1_ItemInserted(object sender, DetailsViewInsertedEventArgs e) 
    { 
     if (e.Exception != null) 
     { 
      lblError.Text = "A database error has occurred.<br /><br />" + "Message: " + e.Exception.Message; 
      e.ExceptionHandled = true; 
      e.KeepInInsertMode = true; 
     } 
     else 
      DetailsView1.DataBind(); 
     DropDownList1.DataBind(); 

    } 

希望有所幫助。

0

如果您的意思是如何避免數據庫級別的併發錯誤,您可以通過您用來更新記錄的代碼來實現。

Here's關於這個問題的一個很好的鏈接。還有很多其他的。

如果你的意思是「如何防止用戶開始編輯其他人正在更新另一個GridView過程中的記錄」,那將會更加複雜。有很多不同的方法可以做到這一點,但我想我會考慮保留正在更新的記錄的ID的緩存,並提供一些用於過期條目的方法(在用戶開始編輯但漫遊的情況下關機,系統故障,否則永遠不會完成)。

相關問題