Hi,
I am experiencing issues with my database instance in your SQL service.
The program we are developing uses that database.
When I test it in a single thread, the ODBC driver works fine. However, when I use multiple threads, I occasionally encounter an 'Invalid cursor state' error message: '[Microsoft][ODBC Driver 17 for SQL Server] Invalid cursor state.'
I have thoroughly reviewed threads and C++ code and cannot identify any collisions or issues. The ODBC driver error occurs specifically when one thread attempts to execute a SQL procedure with a local cursor. To provide more context, I have included the structure of the procedure below, illustrating how the cursor is used.
Your assistance in resolving this issue would be greatly appreciated.
Maybe interesting facts:
- Each thread communicates with db almost constantly.
- The number of threads used ranges from 4 to 10;
- The program works fine with local Microsoft SQL Server 2019 and Amazon SQL service(which I have tested);
- I'm testing program on a virtual machine in Azure Cloud and I get the same error.
- I googled last 7 days and didn't find solution that helped.
Additional questions:
- Are there any limits regarding memory or execution time?
- If yes, how can I change them and what will be optimal values?
- Could this be the reason for the 'invalid cursor state'?
- On my local MSSQL server, I can find logs at: "\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\Log" - How can I access them in your service for my database instance?
SQL procedure structure:
create proc someProcedure @refNumber bigint
as
set nocount on
begin transaction
declare @value1 as int
declare @value2 as varchar(32)
declare @value3 as int
-- Lock, resource name is refNumber in string form (meaning, one lock per refNumber)
declare @result as int
declare @LockedResource as varchar(16)
set @LockedResource = str(@refNumber,16)
exec @result = sp_getapplock @Resource = @LockedResource, @LockMode = 'Exclusive'
if (@result < 0)
set @value2 = 'ERROR: sp_getapplock failed with code:' + ltrim(str(@result,3))
else
begin
declare uCursor cursor local for
select value1, value2, value3 from Table where Id = @refNumber
for update
open uCursor
fetch next from uCursor
into @value1, @value2, @value3
-- checking and changing values @value1, @value2, @value3
-- uses too getdate(), datepart() functions
-- Update Table row
if (substring(@value2, 1, 6) <> 'ERROR:')
begin
update Table set value1=@value1, value2=@value2, value3=@value3
where current of uCursor
end
close uCursor
deallocate uCursor
exec sp_releaseapplock @Resource = @LockedResource
end
commit transaction
set nocount off
select @value2 as Result;
Thank you, Bojan