1

スレッド内で単純なクエリを実行すると、デッドロック エラーが発生する理由を理解しようとしています。Windows 2012 サーバーで SQL Server 2008 R2 を使用して CF10 を実行しています。

1 日に 1 回、一連のブログ フィードをデータベースにキャッシュするプロセスがあります。ブログ フィードごとにスレッドを作成し、そのスレッド内ですべての作業を行います。エラーなしで正常に実行される場合もあれば、1 つ以上のスレッドで次のエラーが発生する場合もあります。

[Macromedia][SQLServer JDBC Driver][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

This approach has been working well for me.

 <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) {
 } 

}  

After all, the message does say to re-run the transaction.

于 2015-05-20T12:02:04.667 に答える