我正在重构遗留应用程序。有问题的应用程序使用SQL Server数据库表对由一个或多个Windows服务检索和处理的作业进行排队。我想创建一个迭代器,它将处理“等待”状态的下一个排队作业进行处理,同时保持正确的锁定。样本单元测试包括在下面。我的问题是我的方法是否有任何潜在的暗示。
// 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);
}
}
}
}