SQL тупик в потоке ColdFusion
Я пытаюсь выяснить, почему я получаю ошибку взаимоблокировки при выполнении простого запроса в потоке. Я использую CF10 с SQL Server 2008 R2 на сервере Windows 2012.
Раз в день у меня есть процесс, который кэширует кучу блогов в базе данных. Для каждого блога я создаю тему и делаю всю работу внутри нее. Иногда он работает без ошибок, иногда я получаю следующую ошибку в одном или нескольких потоках:
[Macromedia] [Драйвер JSBC SQLServer][SQLServer] Транзакция (идентификатор процесса 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 */
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) {
}
}
В конце концов, в сообщении говорится о повторном запуске транзакции.