I have a simple SP that will either do an INSERT or an UPDATE depending on the existence or non-existence of data in a table.
CREATE PROCEDURE [dbo].spUpsert
-- Parameters to Update / Insert a StudentSet
@StudentSetId nvarchar(128),
@Status_Id int
AS
BEGIN
BEGIN TRY
BEGIN TRANSACTION
SET XACT_ABORT ON;
SET NOCOUNT ON;
IF EXISTS(SELECT StudentSetId FROM StudentSet WHERE StudentSetId = @StudentSetId)
BEGIN
UPDATE StudentSet SET ModifiedDate = GETDATE(), Status_Id = @Status_Id
WHERE StudentSetId = @StudentSetId;
END
ELSE
BEGIN
INSERT INTO StudentSet
(StudentSetId, Status_Id)
VALUES
(
@StudentSetId,
@Status_Id
)
END
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
END CATCH
END
Wrote a method like so:
public void Upsert(string studentSetId, int statusId)
{
this.DatabaseJobs.ExecuteSqlCommand(@"exec spUpsert
@StudentSetId = {0},
@Status_Id = {10} ",
studentSetId,
statusId);
}
Here's how this is used: A student has a file, an xml to be precise, that is sent to a processor which calls this SP as part of the process. Multiple files can be uploaded and the processor is designed to work with 5 files spawning 5 threads.
For a batch of 5 files it throws this error:
Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 1, current count = 0. Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 1, current count = 0.
The number 5 is not a perfect one, it may happen when more that 5 files are uploaded. Lesser than that I haven't tried.
So I searched and found a solution that implements the usage of @@TRANCOUNT detailed here & here
@@TRANCOUNT is a global variable and it's usage as suggested in the articles seem's like it's local to the session. What I mean is that any process in SQL Server can increase the @TRANCOUNT and relying on that may not produce the expected result.
My question is what's a good way to handle this type of situation?
Thanks in advance.