Prashant Sharma Ответов: 0

Ошибка взаимоблокировки в MSSQL 2012


Я стою лицом к лицу
"Transaction (Process ID 426) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction."
также некоторое время получаю эту ошибку
"Violation of UNIQUE KEY constraint 'UK_UserTotalEntry_VoucherNo'. Cannot insert duplicate key in object 'dbo.UserTotalEntry'. The duplicate key value is (89295/37029)"
эта ошибка какое-то время приходит и не приходит. Кроме того, я не могу генерировать эту ошибку снова, я пробовал много раз. Я пытаюсь вставить данные оптом с помощью datatable и создал типизированную таблицу в БД. Я делюсь своими кодами ниже и прошу о помощи, а также использую общий хостинг-план Go daddy, в котором я ничего не могу изменить в своей БД. Заранее спасибо.

Что я уже пробовал:

vb.net код
Public Function SaveUpdate(ByVal Action As String)
    Dim Msg As String = Nothing

    Try
        Dim dt_bulk As New DataTable
        dt_bulk.Columns.Add("VoucherNo")
        dt_bulk.Columns("VoucherNo").Expression = "'" & lbl_vno.Text & "'"
        dt_bulk.AcceptChanges()

        Dim dt_Update As New DataTable
        dt_Update = dgv_manualentryedit.DataSource

        dt_bulk.Merge(dt_Update)

        If cn.State = ConnectionState.Closed Then cn.Open()

        Dim ds As New DataSet()
        cmd = New SqlCommand("Proc_dml_SaveUpdate")

        cmd.Parameters.AddWithValue("@NumberEntry", dt_bulk)
        cmd.Parameters.AddWithValue("@VoucherNo", lbl_vno.Text)
        cmd.Parameters.AddWithValue("@date", CustomDate(dtp_Date.Value))
        cmd.Parameters.AddWithValue("@GameMasterId", GameMasterID)
        cmd.Parameters.AddWithValue("@ProfitID", ProfitIDNo)
        cmd.Parameters.AddWithValue("@TotalAmt", lbl_mamount.Text)
        cmd.Parameters.AddWithValue("@CreatedBy", LoginID)
        cmd.Parameters.AddWithValue("@Action", Action)
        cmd.Parameters.AddWithValue("@DeviceID", "2")

        cmd.Connection = cn
        cmd.CommandType = CommandType.StoredProcedure
        cmd.CommandTimeout = 9000
        adapter = New SqlDataAdapter(cmd)
        adapter.Fill(ds)

        If DsJantri.Tables.Count = 1 Then
            ds.Tables(0).TableName = "Status"
        Else
            ds.Tables(0).TableName = "PartyDetail"
            ds.Tables(1).TableName = "Status"
        End If



    Catch ex As Exception
        ShowErrorMsg(ex, Me.Name, MethodInfo.GetCurrentMethod().Name)
        Return False
    End Try

    Return True
End Function

--моя хранимая процедура
ALTER PROCEDURE [dbo].[Proc_dml_SaveUpdate]
    @NumberEntry NumberEntry READONLY,
    @VoucherNo varchar(50),
    @date varchar(10),
    @GameMasterId int,
    @ProfitID int,
    @TotalAmt int,
    @CreatedBy int,
    @Action Varchar(50),
    @DeviceID varchar(2)
AS
BEGIN

  Begin Tran
  SET NOCOUNT ON;	  
  BEGIN TRY 
declare  @CrDateTime datetime =CAST(SWITCHOFFSET(SYSDATETIMEOFFSET(), '+05:30') AS datetime) 
if @Action = 'Save'
begin 
 insert into UserTotalEntry (VoucherNo,date,GameMasterId,ProfitID,TotalAmt,CreatedBy,CreatedOn,DeviceID)
 values  (@VoucherNo , convert(date,('' + @date + ''),103),@GameMasterId, @ProfitId ,@TotalAmt,@CreatedBy,@CrDateTime,@DeviceID)
end   
else if @Action='Update'
begin
 update UserTotalEntry set TotalAmt=@TotalAmt,ModifyOn= @CrDateTime,ModifyBy=@CreatedBy  where VoucherNo=@VoucherNo
 Delete from numberentry where VoucherNo=@VoucherNo
end		 
  INSERT INTO NumberEntry (VoucherNo,Number,Amount,ID)
  SELECT VoucherNo,Number,Amount,ID FROM @NumberEntry

  update  numberentry  set number='0'+number where len(number)=1 and voucherno=@VoucherNo
  
  update numberentry set id = 'BB' where len(number)= 3  and number <> 100  and isnull(id,'') ='' and voucherno=@VoucherNo


  If (@@Error <> 0)  
 Begin          
    rollback transaction       
 End 
 else 
 commit transaction 
		

 select ut.voucherno as'VoucherNo' ,g.GameMasterName ,u.UserName as 'AccountName',
 ut.TotalAmt from usertotalentry  ut  
 left join ProfitnLossAc p on p.profitid =ut.profitid 	
 left join users u on u.UserId =p.UserId 
 left join gamemaster g on g.GameMasterId= ut.GameMasterId
 where ut.voucherno=@VoucherNo

  select 'Entry Saved' as 'Action'


END TRY  


  BEGIN CATCH  

IF @@TRANCOUNT > 0
  ROLLBACK TRANSACTION 

 insert into DbErrorLogs     
 SELECT  
    ERROR_NUMBER() AS ErrorNumber  
    ,ERROR_SEVERITY() AS ErrorSeverity  
    ,ERROR_STATE() AS ErrorState  
    ,ERROR_PROCEDURE() AS ErrorProcedure  
    ,ERROR_LINE() AS ErrorLine  
    ,ERROR_MESSAGE() AS ErrorMessage 
    ,@CrDateTime as 'Datetime'
	,@CreatedBy as LoginID

	
	  select 'Entry Failed' as 'Action'
	  			                          
    END CATCH;


END

Gerry Schmitz

Не "вставляйте данные оптом", когда другие процессы обновляют базу данных. Транзакция включает в себя несколько записей, а не "большую часть".

Prashant Sharma

Сэр, пожалуйста, помогите мне любым альтернативным способом, потому что я беру данные из datagrid и передаю их в datatable, если я использую цикл, то это займет много времени.

Gerry Schmitz

Это потребует знания времени выполнения и рабочих графиков. Редизайн потребует знания бизнес-правил.

0 Ответов