azure web 作业因唯一约束而失败 - 假设由于其他线程
azure web job fails on unique constraint - assuming due to other thread
我有代码检查记录是否存在,如果不存在则插入它。
问题是它有时会失败。
它正在从消息队列中拉取。
我已经做了我能想到的一切,但它以某种方式在另一个'thread'(我假设)上创建记录在它检查之后和创建新记录之前的某个时间。
错误出现在 try / catch 循环中 -- 这有效,但我想知道如何首先避免它发生。
我做错了什么,或者我可以做些什么更好?
代码是这样开始的:
public class Functions
{
// This function will get triggered/executed when a new message is written
// on an Azure Queue called queue.
public static void ProcessQueueMessage([QueueTrigger("stops-to-import-to-mobile")] string message, TextWriter log)
{
剩下的代码...然后麻烦就开始了
mobileEntities mdbPcs = new mobileEntities(); //get a new context for the below
//now go create all the pcs for this stop.
var stopPieces = (from sp in db.Stop_Items where sp.stop_detail_id == stop.Id select sp).ToArray();
//get the count of the current pcs for the enxt stop
int mobilePcCount = (from s in mdbPcs.mobile_Item_Detail where s.mobile_stops_id == mstopId select s.Id).Count();
if (mobilePcCount != stopPieces.Count()) //if the piece count is the same already then no need to go through the loop
{
foreach (var item in stopPieces)//step through the items one at a time
{
int seek = (from s in mdbPcs.mobile_Item_Detail
where s.mobile_stops_id == mstopId &&
s.unique_scan_code == item.item_detail.unique_scan_code
select s.Id).FirstOrDefault();
if (seek == 0) //if we do not already have the item create it
{
mobile_Item_Detail newItem = new mobile_Item_Detail();
newItem.item_description = item.item_detail.item_description;
newItem.LOB_item_detail_id = item.item_detail.Id;
newItem.mobile_stops_id = mstopId;
newItem.dt_seq_no = item.item_detail.dt_item_seq_no;
newItem.unique_scan_code = item.item_detail.unique_scan_code;
mdbPcs.mobile_Item_Detail.Add(newItem);
try
{
mdbPcs.SaveChanges();
}
catch (Exception ex)
{
if (ex.InnerException.InnerException.Message.Contains("UNIQUE KEY")) //WTH -- Why does this keep happening...how do I fix this??!
{
Console.WriteLine($"{DateTime.Now}Unique Contraint {message} {newItem.unique_scan_code} for stop {newItem.mobile_stops_id}");
//item was already created by another thread so continue the foreach loop (I guess?!)
continue;
}
throw;
}
}
}
}
我假设 mobile_Item_Detail
有一个 Id 属性 表示身份 PK,mstopid
是与父项的 FK 关系。在那种情况下,我将对实体集合进行所有更改,然后在 foreach 外部调用保存更改。这样,DbContext 可以一次处理所有 ID,因为它通过 ChangeTracker 了解所有更改,并且可以在单个数据库调用中执行保存。您还可以将操作包装在事务中,以便在发生错误时轻松回滚更改。我还将操作包含在 using 语句中,以确保数据源关闭的连接(参见 here)。
using (var mdbPcs = new mobileEntities ()) //get a new context for the below
{
//now go create all the pcs for this stop.
var stopPieces = (from sp in db.Stop_Items where sp.stop_detail_id == stop.Id select sp).ToArray ();
//get the count of the current pcs for the enxt stop
var mobilePcQuery = (from s in mdbPcs.mobile_Item_Detail where s.mobile_stops_id == mstopId select s.Id);
int mobilePcCount = mobilePcQuery.Count ();
if (mobilePcCount != stopPieces.Count ()) //if the piece count is the same already then no need to go through the loop
{
try
{
foreach (var item in stopPieces) //step through the items one at a time
{
int seek = mobilePcQuery.Where(s => s.unique_scan_code == item.item_detail.unique_scan_code select s.Id).FirstOrDefault ();
if (seek == 0) //if we do not already have the item create it
{
mobile_Item_Detail newItem = new mobile_Item_Detail ();
newItem.item_description = item.item_detail.item_description;
newItem.LOB_item_detail_id = item.item_detail.Id;
newItem.mobile_stops_id = mstopId;
newItem.dt_seq_no = item.item_detail.dt_item_seq_no;
newItem.unique_scan_code = item.item_detail.unique_scan_code;
mdbPcs.mobile_Item_Detail.Add (newItem);
}
}
mdbPcs.SaveChanges ();
} catch (Exception ex) {
if (ex.InnerException.InnerException.Message.Contains ("UNIQUE KEY")) //WTH -- Why does this keep happening...how do I fix this??!
{
Console.WriteLine ($"{DateTime.Now}Unique Contraint {message} {newItem.unique_scan_code} for stop {newItem.mobile_stops_id}");
//item was already created by another thread so continue the foreach loop (I guess?!)
continue;
}
throw;
}
}
}
如果有帮助请告诉我。
我有代码检查记录是否存在,如果不存在则插入它。 问题是它有时会失败。 它正在从消息队列中拉取。 我已经做了我能想到的一切,但它以某种方式在另一个'thread'(我假设)上创建记录在它检查之后和创建新记录之前的某个时间。
错误出现在 try / catch 循环中 -- 这有效,但我想知道如何首先避免它发生。 我做错了什么,或者我可以做些什么更好?
代码是这样开始的:
public class Functions
{
// This function will get triggered/executed when a new message is written
// on an Azure Queue called queue.
public static void ProcessQueueMessage([QueueTrigger("stops-to-import-to-mobile")] string message, TextWriter log)
{
剩下的代码...然后麻烦就开始了
mobileEntities mdbPcs = new mobileEntities(); //get a new context for the below
//now go create all the pcs for this stop.
var stopPieces = (from sp in db.Stop_Items where sp.stop_detail_id == stop.Id select sp).ToArray();
//get the count of the current pcs for the enxt stop
int mobilePcCount = (from s in mdbPcs.mobile_Item_Detail where s.mobile_stops_id == mstopId select s.Id).Count();
if (mobilePcCount != stopPieces.Count()) //if the piece count is the same already then no need to go through the loop
{
foreach (var item in stopPieces)//step through the items one at a time
{
int seek = (from s in mdbPcs.mobile_Item_Detail
where s.mobile_stops_id == mstopId &&
s.unique_scan_code == item.item_detail.unique_scan_code
select s.Id).FirstOrDefault();
if (seek == 0) //if we do not already have the item create it
{
mobile_Item_Detail newItem = new mobile_Item_Detail();
newItem.item_description = item.item_detail.item_description;
newItem.LOB_item_detail_id = item.item_detail.Id;
newItem.mobile_stops_id = mstopId;
newItem.dt_seq_no = item.item_detail.dt_item_seq_no;
newItem.unique_scan_code = item.item_detail.unique_scan_code;
mdbPcs.mobile_Item_Detail.Add(newItem);
try
{
mdbPcs.SaveChanges();
}
catch (Exception ex)
{
if (ex.InnerException.InnerException.Message.Contains("UNIQUE KEY")) //WTH -- Why does this keep happening...how do I fix this??!
{
Console.WriteLine($"{DateTime.Now}Unique Contraint {message} {newItem.unique_scan_code} for stop {newItem.mobile_stops_id}");
//item was already created by another thread so continue the foreach loop (I guess?!)
continue;
}
throw;
}
}
}
}
我假设 mobile_Item_Detail
有一个 Id 属性 表示身份 PK,mstopid
是与父项的 FK 关系。在那种情况下,我将对实体集合进行所有更改,然后在 foreach 外部调用保存更改。这样,DbContext 可以一次处理所有 ID,因为它通过 ChangeTracker 了解所有更改,并且可以在单个数据库调用中执行保存。您还可以将操作包装在事务中,以便在发生错误时轻松回滚更改。我还将操作包含在 using 语句中,以确保数据源关闭的连接(参见 here)。
using (var mdbPcs = new mobileEntities ()) //get a new context for the below
{
//now go create all the pcs for this stop.
var stopPieces = (from sp in db.Stop_Items where sp.stop_detail_id == stop.Id select sp).ToArray ();
//get the count of the current pcs for the enxt stop
var mobilePcQuery = (from s in mdbPcs.mobile_Item_Detail where s.mobile_stops_id == mstopId select s.Id);
int mobilePcCount = mobilePcQuery.Count ();
if (mobilePcCount != stopPieces.Count ()) //if the piece count is the same already then no need to go through the loop
{
try
{
foreach (var item in stopPieces) //step through the items one at a time
{
int seek = mobilePcQuery.Where(s => s.unique_scan_code == item.item_detail.unique_scan_code select s.Id).FirstOrDefault ();
if (seek == 0) //if we do not already have the item create it
{
mobile_Item_Detail newItem = new mobile_Item_Detail ();
newItem.item_description = item.item_detail.item_description;
newItem.LOB_item_detail_id = item.item_detail.Id;
newItem.mobile_stops_id = mstopId;
newItem.dt_seq_no = item.item_detail.dt_item_seq_no;
newItem.unique_scan_code = item.item_detail.unique_scan_code;
mdbPcs.mobile_Item_Detail.Add (newItem);
}
}
mdbPcs.SaveChanges ();
} catch (Exception ex) {
if (ex.InnerException.InnerException.Message.Contains ("UNIQUE KEY")) //WTH -- Why does this keep happening...how do I fix this??!
{
Console.WriteLine ($"{DateTime.Now}Unique Contraint {message} {newItem.unique_scan_code} for stop {newItem.mobile_stops_id}");
//item was already created by another thread so continue the foreach loop (I guess?!)
continue;
}
throw;
}
}
}
如果有帮助请告诉我。