6

我正在重构遗留应用程序。有问题的应用程序使用 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);
            }
        }
    } 
}
4

0 回答 0