I have a C# process that is inserting records into a table within a transaction. During this time another process (an SQL stored procedure) is updating this table. The C# process is using serializable isolation mode and the SP is using read commit.
The table being updated has a datetime field named DateShipped which the C# process is inserting using the current time. It takes about 1s for the C# process to determine the values to use and execute the insert statement. Looking at the data in the table you can see all the records added within the transaction have about a 1s difference in the DateShipped field. Let's not worry about how to make this process better. I'm currently concerned with understanding how the SP is able to update a record that is within the transaction of another process and has not been committed.
There is another field TransID in the table defined as INT. The C# process is not specifying a value for this field when inserting so it defaults to NULL. The SP runs on a schedule and the first thing it does is update all the records where TransID IS NULL to a specified value. The SP is running within an explicit transaction.
There are times (not sure if it is always as I don't know how often they both run at the exact same time) when some of the records (the first so many) get updated with a TransID when the others within the same transaction do not.
How is it that the SP can see the first so many records, but not all of them?
Is there a way to use Extended Events to capture this?
Insert Results:
DateShipped TransID
2020-02-12 00:26:47.680 514928
2020-02-12 00:26:49.090 514929
2020-02-12 00:26:50.057 514929
2020-02-12 00:26:51.027 514929
2020-02-12 00:26:51.963 514929
2020-02-12 00:26:52.887 514929
2020-02-12 00:26:53.807 514929
2020-02-12 00:26:54.747 514929
2020-02-12 00:26:55.713 514929
2020-02-12 00:26:56.700 514929
2020-02-12 00:26:57.700 514929
2020-02-12 00:26:58.653 514929
2020-02-12 00:26:59.620 514929
2020-02-12 00:27:00.573 514929
Can someone recommend a way to prevent this (updating an uncommitted insert from a different transaction) or capture relative information to show this is happening?
Additional Information
Process 1 Code (c#)
ADODB.Connection.BeginTrans()
... Several inline SELECTs and INSERTs via ADODB.Connection.Execute()
ADODB.Connection.CommitTrans()
The insert is setting the DateShipped field to the current date/time. So the DateShipped is the date/time of the insert.
Process 2 Code (stored procedure)
BEGIN TRANSACTION
SELECT @ID = (MAX(TransID) + 1) FROM dbo.tHostInterfaceExport
INSERT INTO dbo.tHostInterfaceExport ( TransID ) VALUES (@ID)
EXEC dbo.dloc_UpdateActivityTables @ID
COMMIT TRANSACTION
PROCEDURE dbo.dloc_UpdateActivityTables @TransID INT
UPDATE dbo.tActivityShipments
SET TransID = @TransID
WHERE TransID IS NULL
The issue is this UPDATE statement sometimes (probably only when the 2 processes run at the same time) only updates some of the first records inserted in process 1.
Here's another sample of data where the issue has happened. All of these records were written within the same transaction of process 1.
DateShipped TransID
2020-02-12 10:54:29.157 244878
2020-02-12 10:54:30.063 244878
2020-02-12 10:54:30.940 244878
...
2020-02-12 10:56:31.290 244878
2020-02-12 10:56:31.867 244878
2020-02-12 10:56:32.493 244878 <-- why was this one and the above ones updated
2020-02-12 10:56:33.087 244879 <-- and not this one and the ones below?
2020-02-12 10:56:33.730 244879
2020-02-12 10:56:34.353 244879
...
2020-02-12 10:57:32.360 244879
2020-02-12 10:57:33.093 244879
2020-02-12 10:57:33.970 244879
Addition information as to when the TransID are created. The TransID is created at the start of process 2. This shows that process 2 was called at 2 separate times and 3 minutes apart.
TransID DateCreated
244878 2020-02-12 10:54:56.817
244879 2020-02-12 10:57:56.880
What's interesting here is that process 2 is scheduled to run every 60s, yet it was held up (waiting for process 1 to finish and commit the transaction) before finishing TransID 244878. I say this because the entry for TransID = 244879 should of happened at 10:55:56 or 10:56:56, but the process was still waiting for the previous update that was being blocked by the insert transaction which finished after the last insert at 10:57:33.970.