I originally proposed SQL Server Service Broker for this. However, after some research, it turns out that this is probably not the best way to deal with this problem.
What remains for you is the architecture of the table you requested. However, as you have found, it is unlikely that you will be able to come up with a solution that meets all the specified criteria, due to the high complexity of blocking, transactions, and the pressure imposed on such a scheme by high concurrency and high transactions per second.
Note. I am currently studying this issue and will come back to you later. The following script was my attempt to fulfill these requirements. However, he suffers from frequent dead ends and processes out of order. Please stay tuned and in the meantime consider the destructive read method (DELETE WITH OUTPUT or OUTPUT INTO).
SET XACT_ABORT ON; -- blow up the whole tran on any errors SET TRANSACTION ISOLATION LEVEL READ COMMITTED; BEGIN TRAN UPDATE X SET X.StatusID = 2 -- in process OUTPUT Inserted.* FROM ( SELECT TOP 1 * FROM dbo.QueueTable WITH (READPAST, ROWLOCK) WHERE StatusID = 1 -- ready ORDER BY QueuedDate, QueueID -- in case of items with the same date ) X; -- Do work in application, holding open the tran. DELETE dbo.QueueTable WHERE QueueID = @QueueID; -- value taken from recordset that was output earlier COMMIT TRAN;
In the case when several / several rows are blocked at once by one client, there is a possibility that the row lock will increase to a degree, page or table lock, so keep this in mind. In addition, usually long-running transactions that support locks are large, no, no. It may work in this special use case, but I'm afraid that high tps by several clients will cause the system to break. Note that, as a rule, the only processes that request your queue table should be those that do the work in the queue. Any reporting processes should use READ UNCOMMITTED or WITH NOLOCK to avoid queuing in some way.
What does it mean that strings are processed out of order? If the application instance crashes when another instance successfully completes the lines, this delay is likely to delay at least one line at its completion, which will lead to an incorrect processing order.
If the transaction / lock method above does not meet your satisfaction, another way to deal with the application crash is to provide the names of your instances, and then set up a monitoring process that can periodically check if these named instances are running. When the named instance is started, there will always be reset any unprocessed lines that have their instance id (something simple like "instance A" and "instance B"). In addition, the monitoring process checks to see if the instances are running, and if one of them does not work, reset the lines for this missing instance, allowing any other instances to run. There would be a slight lag between failure and recovery, but with proper architecture, this could be perfectly reasonable.
Note. The following links should be called: