Sql server 控制azure WebJob函数调用
我有一个Azure连续web作业,它有两种方法。第一个方法CleanupDb是[Singleton],每5分钟触发一次,第二个多线程方法ProcessXML使用队列触发。ProcessXml将数据从blob存储中存储的xml大容量复制到数据库,但当CleanupDb方法运行时,我希望:Sql server 控制azure WebJob函数调用,sql-server,multithreading,azure,azure-webjobs,azure-webjobssdk,Sql Server,Multithreading,Azure,Azure Webjobs,Azure Webjobssdk,我有一个Azure连续web作业,它有两种方法。第一个方法CleanupDb是[Singleton],每5分钟触发一次,第二个多线程方法ProcessXML使用队列触发。ProcessXml将数据从blob存储中存储的xml大容量复制到数据库,但当CleanupDb方法运行时,我希望: 在CleanupDb期间挂起ProcessXml的队列触发器 等待ProcessXml的任何当前实例完成 对数据库执行更新 数据库清理完成后,重新启用对ProcessXml的调用 我怎样才能做到这一点?我是否需要
[Singleton]
public async static Task CleanupDb([TimerTrigger("0 0/5 * * * *", RunOnStartup = false)]TimerInfo info, TextWriter log)
{
// disable any calls to ProcessXML based on import-request queue
// Wait for any current calls to ProcessXML to complete
using (XmlNetworkModel ctxt = new XmlNetworkModel())
{
ctxt.Database.CommandTimeout = 0;
await ctxt.Database.ExecuteSqlCommandAsync("exec stpCleanupDb");
}
// re-enable calls to ProcessXML
}
// This function will get triggered/executed when a new message is written
// on an Azure Queue called queue.
public async static Task ProcessXML(
[QueueTrigger("import-request")] BlobInformation blobInfo,
[Blob("import/{BlobName}", FileAccess.Read)] Stream blobInStream,
[Blob("import/{BlobName}")] CloudBlockBlob blobIn, TextWriter log)
{
using (SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(ConfigurationManager.ConnectionStrings["model"].ConnectionString,
SqlBulkCopyOptions.TableLock)) // should TableLock be used with parallel threads here?
{
await sqlBulkCopy.WriteToServerAsync([mydatafromblobInStream]);
}
}
一旦队列触发器运行,就无法临时禁用它。我还要提到,默认情况下TimerTrigger已经是单例的了。它在后台使用单例锁,以确保只有一个调度函数的实例在扩展实例上运行。因此,可能不需要额外的单例属性 一种选择是在两个函数上使用singleton,使用相同的锁作用域(例如,
[singleton(“xmlimport”)]
)。这将确保函数不会同时运行——它们都需要相同的锁。例如,当运行CleanupDB
时,任何ProcessXML
调用都将等待锁定,反之亦然。这样做的一个潜在缺点是,您的队列函数现在也将被序列化——一次只处理一条队列消息,即使您的clean函数没有运行。如果您希望队列具有高吞吐量,那么您可能不希望这样。但是,如果导入操作不经常发生,这可能是您的一个选择
如果您已经将WebJob扩展到多个实例,那么使用进程内同步将不起作用,您将再次需要类似Singleton提供的某种分布式锁定
另一种选择是确保数据库清理存储过程可以并发运行,这样就不必担心同步问题。不确定这是否是你的选择。例如,确保清理操作仅对旧数据进行操作,以便进行中的导入不会产生干扰,等等。因此,事实证明,您当前不能像上面所述那样在函数实例中实际使用单例。默认情况下,用于锁的blob路径始终包含完全限定的函数名。我已经在我们的公共回购协议中创建了一个应用程序来启用此场景。谢谢-看起来最好的选择可能是确保cleanupdb只在“旧”数据上运行。为了有效地做到这一点,我可能需要某种“滚动”分区方案——我一直在研究这个问题。可能是因为BulkCopy正在放置TabLock,所以清理数据库当前不工作-我将尝试删除它。查看github-我认为我是正确的,Singleton作用域的问题现在已通过azure web job sdk 1.1.1解决。是的,1.1.1中添加了对此的支持。你可以在维基上阅读更多。谢谢mathewc。当我对两个或多个计时器函数使用相同的单例锁时会发生什么?如果一个进程锁定另一个进程,那么锁定的进程会在失败时重试吗?例如,如果我有一个计时器每5分钟启动一次,如果5分钟的计时器进程发生溢出并“锁定”,那么每天的计时器是否会在不等待24小时的情况下重试?