I am reorganizing an outdated application. This application uses the SQL Server database table to queue jobs that are received and processed by one or more Windows services. I want to create an iterator that pulls the next job in the queue with the status "Waiting" for processing, while maintaining the correct locks. An example unit test is given below. My question is whether there are any potential showstoppers with my approach.
// Database DDL if object_id('Jobs') is not null begin drop table Jobs; end go create table Jobs ( Id int identity(1,1) not null primary key clustered , JobStatus varchar(50) not null ); insert Jobs select 'Waiting' union all select 'Waiting' union all select 'Processing' union all select 'Completed' union all select 'Failed'; // Unit Test // Data Model public sealed class Job { public readonly int JobId; public Job(int jobId) { JobId = jobId; } } [TestFixture] public class JobsTest { private const string connectionString = "Data Source=.;Initial Catalog=<databasename>;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=False"; const string SQL = @"declare @jobId table(JobId int) update top(1) Jobs set JobStatus = 'Processing' output Inserted.Id into @jobId where JobStatus = 'Waiting' select JobId from @jobId;"; [Test] public void CanIterateJobs() { foreach (var job in Jobs) { Assert.NotNull(job, "job was null."); Console.WriteLine(job.JobId); } } public static IEnumerable<Job> Jobs { get { while (true) { Job job = null; do { using (var connection = new SqlConnection(connectionString)) { using (var command = new SqlCommand(SQL, connection)) { connection.Open(); var reader = command.ExecuteReader(); if (reader.Read()) { job = new Job(Convert.ToInt32(reader["JobId"])); yield return job; } } } } while (job == null); Task.Delay(1000); } } } }
user280610
source share