我有一个asp.net mvc 3网站,当一个人编辑任务时,它会锁定该任务,以便他们可以编辑它并确保其他订阅者在编辑任务时不会删除或更新任务。
他们点击任务上的编辑,然后抓住任务并锁定它。他们编辑任务并更新。
现在我有类似的东西
public Task Update(Task task)
{
isLocked = true;
try
{
// set task to unlock itself(this is stored on the task row in the db)
task.locked = false
task.DateLocked = "6/3/1900";
task.Commit(); // save the newly updated task; - nhibernate
isLocked = false;
return task
}
catch(SqlException ex)
{
// error logging here
// "database is down error to user"
}
finally
{
if(isLocked)
{
task.locked = false
task.DateLocked = "6/3/1900";
task.Commit();
}
}
}
如果任务成功更新,文件将被解锁,所以我不打算在finally中再次执行此操作。如果我遇到一些意外错误,比如空引用(因为我检查任何可能为null并导致异常的东西,但是假装它会以某种方式发生)。
我的最终声明将启动并确保解锁的文件当然会爆炸并且用户会得到一些通用的“出错的错误”,但文件将被解锁,以便他们可以再试一次。
现在如果错误是SqlException错误会发生什么?它会被抓住,但最后的声明仍然会运行,它也会在那里爆炸。
我是否应该在另一个try catch中将finally代码中的代码包装起来?
我确实有一个经常运行的计划任务,以确保最终将解锁任务,因此如果数据库已关闭,那么任务永远不会被锁定,最终应解锁。
答案 0 :(得分:2)
从这种情况来看,你似乎没有从最后再次运行commit语句中获得太多好处。你可以做这样的事情来处理像这样的db例外:
public Task Update(Task task)
{
isLocked = true;
try
{
//DO OTHER STUFF HERE
}
catch(Exception ex)
{
// error logging here
}
finally
{
UpdateToDB(task)
}
return task;
}
private Task UpdateToDB(Task task)
{
try
{
task.locked = false
task.DateLocked = "6/3/1900";
task.Commit();
}
catch(Exception e)
{
//LOG ERROR
}
catch(SqlException ex)
{
//LOG ERROR
// "database is down error to user"
}
isLocked = false;
return task
}
答案 1 :(得分:0)
您是否考虑过设置一个标志来指示正在捕获的SQLException,并在finally块中检查该标志并随后采取适当的措施......