1

我试图弄清楚为什么在线程内执行简单查询时会出现死锁错误。我在 Windows 2012 服务器上运行带有 SQL Server 2008 R2 的 CF10。

每天一次,我有一个将一堆博客提要缓存在数据库中的进程。对于每个博客提要,我创建一个线程并在其中完成所有工作。有时它运行良好,没有错误,有时我在一个或多个线程中收到以下错误:

[Macromedia][SQLServer JDBC 驱动程序][SQLServer]Transaction(进程 ID 57)与另一个进程在锁资源上死锁,并已被选为死锁牺牲品。重新运行事务。

当我运行一个设置了一个标志的查询时,会发生这种死锁情况,该标志指示正在更新提要。显然,此查询可能与正在更新其他提要的其他线程同时发生。

根据我的研究,我认为我可以通过在查询周围放置一个独占命名锁来解决这个问题,但我为什么需要这样做呢?我以前从来没有处理过僵局,所以请原谅我对这个问题的无知。我怎么可能遇到死锁情况?

由于要发布的代码太多,这里有一个粗略的算法:

thread name="#createUUID()#" action="run" idBlog=idBlog {

   try {

       var feedResults = getFeed(idBlog);
       if (feedResults.errorCode != 0)
          throw(message="failed to get feed");

       transaction {
           /* just a simple query to set a flag */
           dirtyBlogCache(idBlog); /* this is where i get the deadlock */
           cacheFeedResults(idBlog, feedResults);
       }

       } catch (any e) {
           reportError(e);
       }
   }

} /* thread */
4

1 回答 1

1

这种方法对我来说效果很好。

 <cffunction name="runQuery" access="private" returntype="query">
 arguments if necessary
 <cfset var whatever = QueryNew("a")>
 <cfquery name="whatever">
 sql
 </cfquery>
 <cfreturn whatever>
 </cffunction>

 attempts = 0;
 myQuery = "not a query";
 while (attempts <= 3 && isQuery(myQuery) == false) {
 attempts += 1;
 try {
 myQuery = runQuery();
 }
 catch (any e) {
 } 

}  

毕竟,消息确实说要重新运行事务。

于 2015-05-20T12:02:04.667 回答