二开案例.防止执行计划重复运行原创
金蝶云社区-齐111
齐111
4人赞赏了该文章 27次浏览 未经作者许可,禁止转载编辑于2024年08月26日 15:10:59

在执行计划开始时,将执行计划ID作为主键存到数据库中,执行结束时删除,用主键唯一性保证执行计划不会重复

public class TestScheduleService : IScheduleService
{
	public void Run(Context ctx, Schedule schedule)
	{
		var duplicateCheckId = "Schedule_" + schedule.ScheduleId;   //在执行计划开始时,duplicateCheckId会作为主键存到数据库中,执行结束时删除,用主键唯一性保证执行计划不会重复
		var duplicateCheckTimeoutSenconds = 60 * 60 * 24;   //过期时间1天。执行计划开始时插入的数据长时间没有删除,可能是异常退出了,自动删除过期数据
		using (var duplicateExecutionValidator = new DuplicateExecutionValidator(ctx, duplicateCheckId, duplicateCheckTimeoutSenconds))
		{
			if (duplicateExecutionValidator.IsDuplicateExecution())
			{
				Kingdee.BOS.Log.Logger.Info("DuplicateExecution", "已有任务在运行,退出执行。");
				return;
			}
			//执行计划代码放这里
		}
	}
}

public class DuplicateExecutionValidator : IDisposable
{
	static string TableName = "T_Temp_DuplicateValidator";
	Context Ctx;
	string TaskId;
	string Id;
	int TimeOutSenconds;

	public DuplicateExecutionValidator(Context ctx, string taskId, int timeOutSenconds = 60 * 60 * 24)
	{
		Ctx = ctx;
		TaskId = taskId;
		TimeOutSenconds = timeOutSenconds;
		Id = Guid.NewGuid().ToString();
	}

	public bool IsDuplicateExecution()
	{
		try
		{
			if (!DBUtils.IsExistTable(Ctx, TableName))
			{
				var createTableSql = string.Format(@"
CREATE TABLE {0} (
FID VARCHAR(36) NOT NULL,
FGUID VARCHAR(36) NOT NULL,
FCREATEDATE DATETIME DEFAULT GETDATE() NOT NULL,
CONSTRAINT PK_{0} PRIMARY KEY (FID)
)", TableName);
				DBUtils.Execute(Ctx, createTableSql);
			}

			var isExistsRunningTask = DBUtils.ExecuteScalar<int>(Ctx, string.Format(@"select count(1) from {0} where FID = @FID and FCREATEDATE > @FTimeout", TableName), 0, new SqlParam("@FID", KDDbType.String, TaskId), new SqlParam("@FTimeout", KDDbType.DateTime, DateTime.Now.AddSeconds(-TimeOutSenconds))) > 0;
			if (isExistsRunningTask) return true;
			try
			{
				//删除超时的任务
				var deleteResult = DBUtils.ExecuteScalar<int>(Ctx, string.Format(@"delete from {0} where FID=@FID and FCREATEDATE < @FTimeout", TableName), 0,
				new SqlParam("@FID", KDDbType.String, TaskId),
				new SqlParam("@FTimeout", KDDbType.DateTime, DateTime.Now.AddSeconds(-TimeOutSenconds)));

				var result = DBUtils.Execute(Ctx, string.Format("insert into {0} (FID, FGUID) values (@FID, @FGUID)", TableName), new SqlParam[] { new SqlParam("@FID", KDDbType.String, TaskId), new SqlParam("@FGUID", KDDbType.String, Id) });
				if (result > 0)
				{
					return false;
				}
				else
				{
					return true;
				}
			}
			catch (Exception ex)
			{
				Kingdee.BOS.Log.Logger.Error("DuplicateExecution", ex.Message, ex);
				return true;
			}
		}
		catch (Exception e)
		{
			Kingdee.BOS.Log.Logger.Error("DuplicateExecution", e.Message, e);
			return true;
		}
	}

	public void Dispose()
	{
		DBUtils.Execute(Ctx, string.Format("delete from {0} where FID = @FID and FGUID = @FGUID", TableName), new SqlParam[] { new SqlParam("@FID", KDDbType.String, TaskId), new SqlParam("@FGUID", KDDbType.String, Id) });
	}
}
赞 4