Open hdamis opened 3 years ago
An internal database error occurred. ---> System.Data.SqlClient.SqlException: Transaction (Process ID 66) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
We identified that the
I am also getting a similar issue. I have a huge traffic of nearly 100-1000 updates per second in the listened columns. I update the screen in 3 seconds by querying from DB. The data received in the table changed event cannot suffice my requirement as the grid I show has a JOIN with other 5+ tables.
Is SQLTableDependency ideal for this scenario with this high traffic? Is it worth it if I actually build infrastructure to rerun the transaction? Is there a way to debounce / throttle the trigger from the DB itself?
so please can anyone answer me ?
My experience is that this code does not function particularly well under extremely high load where you have a complex schema and I have seen similar errors to what you describe. Frankly at 100-1000 updates per second I don't believe this library is designed for dealing with such high load, nor do I believe it is appropriate to bombard an SQL database in such a way.
If I was dealing with such a high load I would probably be looking at database designed specifically for such scenarios or at the very least batching my updates in some sort of intermediary service.
With that said I have generally used a retry pattern similar to that described in this question. Along with the following code which ensures that all the queues and contracts related to this library are cleaned up prior to restarting the service.
PRINT 'Starting Killing Services'
DECLARE @name VARCHAR(5000)
DECLARE db_services_cursor CURSOR FOR
SELECT [name] FROM sys.services
WHERE service_id > 3
OPEN db_services_cursor
FETCH NEXT FROM db_services_cursor INTO @name
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT ('Current Name: ' + @name)
EXEC('drop service [' + @name + ']')
FETCH NEXT FROM db_services_cursor INTO @name
END
CLOSE db_services_cursor
DEALLOCATE db_services_cursor
PRINT 'Ended'
PRINT 'Starting Killing Contracts'
DECLARE @contract_name VARCHAR(5000)
DECLARE db_contract_cursor CURSOR FOR
SELECT [name] FROM sys.service_contracts where service_contract_id > 6
OPEN db_contract_cursor
FETCH NEXT FROM db_contract_cursor INTO @contract_name
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT ('Current Name: ' + @contract_name)
EXEC('drop contract [' + @contract_name + ']')
FETCH NEXT FROM db_contract_cursor INTO @contract_name
END
CLOSE db_contract_cursor
DEALLOCATE db_contract_cursor
PRINT 'Ended'
PRINT 'Starting Killing Triggers Procs'
DECLARE @triggers_name VARCHAR(5000)
DECLARE db_triggers_cursor CURSOR FOR
SELECT name FROM sys.triggers WHERE type = 'TR' and name LIKE 'tr_dbo%_Sender'
OPEN db_triggers_cursor
FETCH NEXT FROM db_triggers_cursor INTO @triggers_name
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT ('Current Name: ' + @triggers_name)
EXEC('drop trigger [' + @triggers_name + ']')
FETCH NEXT FROM db_triggers_cursor INTO @triggers_name
END
CLOSE db_triggers_cursor
DEALLOCATE db_triggers_cursor
PRINT 'Ended'
PRINT 'Starting Killing Stored Procs'
DECLARE @storedprocs_name VARCHAR(5000)
DECLARE db_storedprocs_cursor CURSOR FOR
SELECT [name] from sysobjects where type = 'P' and category = 0 and name LIKE '%QueueActivationSender'
OPEN db_storedprocs_cursor
FETCH NEXT FROM db_storedprocs_cursor INTO @storedprocs_name
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT ('Current Name: ' + @storedprocs_name)
EXEC('drop PROCEDURE [' + @storedprocs_name + ']')
FETCH NEXT FROM db_storedprocs_cursor INTO @storedprocs_name
END
CLOSE db_storedprocs_cursor
DEALLOCATE db_storedprocs_cursor
PRINT 'Ended'
PRINT 'Starting Killing Message Types'
DECLARE @messagetype_name VARCHAR(5000)
DECLARE db_messagetype_cursor CURSOR FOR
SELECT [name] FROM sys.service_message_types where message_type_id > 14
OPEN db_messagetype_cursor
FETCH NEXT FROM db_messagetype_cursor INTO @messagetype_name
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT ('Current Name: ' + @messagetype_name)
EXEC('drop MESSAGE TYPE [' + @messagetype_name + ']')
FETCH NEXT FROM db_messagetype_cursor INTO @messagetype_name
END
CLOSE db_messagetype_cursor
DEALLOCATE db_messagetype_cursor
PRINT 'Ended'
PRINT 'Starting Killing Queues'
DECLARE @queue_name VARCHAR(5000)
DECLARE db_queue_cursor CURSOR FOR
SELECT [name] FROM sys.service_queues where is_ms_shipped = 0
OPEN db_queue_cursor
FETCH NEXT FROM db_queue_cursor INTO @queue_name
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT ('Current Name: ' + @queue_name)
EXEC('drop QUEUE [' + @queue_name + ']')
FETCH NEXT FROM db_queue_cursor INTO @queue_name
END
CLOSE db_queue_cursor
DEALLOCATE db_queue_cursor
PRINT 'Ended'
Dear Maxim, but this will drop the trigger and the clients will not notify for any farther changes. as the trigger is dropped. and please tell me do you mean to make a job using the above code or a Stored Procedure and when I have to call it. Thanks,
Hi, I enable Service Broker on my sql server 2012 to use sqltabledependency in vb.net application to notify me on update a field. but recently I saw a trigger on my table which "locks" all upcoming DML operations to this table. the error message is when I trying to update the field " No row was updated. Error Source: .Net SqlClient Data provider. Error Message: Cannot find object ID 467661280 in database ID 49. Correct the errors and retry or press ESC to cancel the change(s). I disable the trigger named(tr_dbo_Appointments_772a313c-6865-4057-95a7-63dc7b7191e3_Sender) and the locks goes. so why this happen and how to avoid it again. below is the trigger which automatically generated. USE [db0001] GO /** Object: Trigger [dbo].[tr_dbo_Appointments_772a313c-6865-4057-95a7-63dc7b7191e3_Sender] Script Date: 02/05/2021 6:28:58 PM **/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER TRIGGER [dbo].[tr_dbo_Appointments_772a313c-6865-4057-95a7-63dc7b7191e3_Sender] ON [dbo].[Appointments] WITH EXECUTE AS SELF AFTER insert, update, delete AS BEGIN SET NOCOUNT ON;
END