I need to lock a row, read and then update a field of this row in SQL Server and Python, for a program that can run multiple process at the same time, to avoid a race condition.
I'm using the following code, but in Python it updates one Id (i.e 3411) and returns another Id (i.e. 3071). If I run the same SQL code directly in SSMS, it updates and returns the same Id.
import pyodbc
def read_and_update_files_queue(self):
conn = pyodbc.connect('Driver={SQL Server};'
'Server='+self.server+';'
'Database='+self.database+';'
'Trusted_Connection=yes;')
cursor = conn.cursor()
sql_query=f'''
BEGIN TRANSACTION;
DECLARE @Temp_ID AS INT
SELECT TOP 1 @Temp_ID=Id
FROM dbo.[Queue]
WITH(XLOCK, ROWLOCK)
WHERE [BQ_status] IS NULL and upload_date IS NOT NULL
Select TOP 1
Id,GCS_path,file_first_upload
FROM dbo.[Queue]
WITH(XLOCK, ROWLOCK)
WHERE Id=@Temp_ID
UPDATE dbo.[Queue] SET BQ_status='Loading'
WHERE Id=@Temp_ID
COMMIT TRANSACTION;
'''
cursor.execute(sql_query)
cursor.commit()
What is wrong? The code is based on this: In SQL Server, how can I lock a single row in a way similar to Oracle's "SELECT FOR UPDATE WAIT"? Thanks!!