Ho una procedura memorizzata, che seleziona 1 record indietro. la stored procedure può essere chiamata da diverse applicazioni su diversi PC. L'idea è che la stored procedure riporti il successivo record che deve essere elaborato, e se due applicazioni chiamano il proc memorizzato nello stesso momento, lo stesso record non dovrebbe essere riportato indietro. La mia domanda è sotto, sto cercando di scrivere la query nel modo più efficiente possibile (sql 2008). Può essere fatto in modo più efficiente di questo?Transazione efficiente, blocco record
CREATE PROCEDURE GetNextUnprocessedRecord
AS
BEGIN
SET NOCOUNT ON;
--ID of record we want to select back
DECLARE @iID BIGINT
-- Find the next processable record, and mark it as dispatched
-- Must be done in a transaction to ensure no other query can get
-- this record between the read and update
BEGIN TRAN
SELECT TOP 1
@iID = [ID]
FROM
--Don't read locked records, only lock the specific record
[MyRecords] WITH (READPAST, ROWLOCK)
WHERE
[Dispatched] is null
ORDER BY
[Received]
--Mark record as picked up for processing
UPDATE
[MyRecords]
SET
[Dispatched] = GETDATE()
WHERE
[ID] = @iID
COMMIT TRAN
--Select back the specific record
SELECT
[ID],
[Data]
FROM
[MyRecords] WITH (NOLOCK, READPAST)
WHERE
[ID] = @iID
END
Io non sono convinto che questo TSQL è transazionale sicuro ... –
prova a mettere un WAITFOR DELAY '0: 2: 0' dopo SELECT e prima dell'aggiornamento, esegui l'SP ed esegui lo stesso SP da un'altra connessione ... –
in realtà, mi sbaglio! HOLDLOCK ha lo stesso effetto di REPEATABLEREAD nella tabella MyRecords. –