2013-05-07 1 views
0

Я построил службу отдыха, чтобы вставить большие строки. Чтобы вставить большое количество строк, я использую вставку пакетами. Что может вызвать тупик в этом фрагменте обслуживания.ConcurrencyFailureException: Тупик при добавлении большого количества строк в партиях

final SqlMapClient sqlMapClient = getSqlMapClientTemplate().getSqlMapClient(); 
    sqlMapClient.startTransaction(); 
    sqlMapClient.startBatch(); 

    //data is of size say 10,000 i am dividing into 500 and inserting 
    do { 
     data500 = next 500 of data 
     getSqlMapClientTemplate().insert("insertData", data500); 
    }while(data500 is not empty) 

    sqlMapClient.executeBatch(); 
    sqlMapClient.commitTransaction(); 

Но я получаю эту ошибку:

 
Description : org.springframework.dao.ConcurrencyFailureException: SqlMapClient operation; SQL []; 
--- The error occurred while applying a parameter map. 
--- Check the insertData-InlineParameterMap. 
--- Check the statement (update failed). 
--- Cause: java.sql.SQLException: Transaction (Process ID 3121) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException: 

ответ

0

Тупики указывают на проблему разработки программы. База данных создает транзакции, которые блокируют данные при изменении данных. Если вы измените данные «A», а затем данные «B», в базе данных будут заблокированы обе эти точки данных. В зависимости от вашей базы данных и настроек фактические блокировки для «A» и «B» могут быть отдельными записями, группами записей (страниц) или даже целыми таблицами.

Если ваша транзакция уже изменила «A» и теперь пытается изменить «B», но какая-то другая программа уже модифицировала «B» и теперь пытается изменить «A», тогда у вас есть тупик ,

Некоторые базы данных (например, DB2) указывают на тупиковую ситуацию, хотя это может быть просто тайм-аут блокировки (процесс проработал 60 секунд, чтобы получить блокировку, но не удалось). У DB2 есть специальные подкоды, указывающие, какова основная причина тупика.

Единственное решение для тупика - это база данных, чтобы выбрать один из процессов, который нужно убить, и пропустить другого. Ваш процесс был убит.

Проблема с блокировкой указывает на проблему с программным обеспечением. Это хорошо известная проблема, и единственным надежным решением является обеспечение того, чтобы все ваши программы блокировали данные в том же порядке, что и другие. Таким образом, вы не получите взаимоблокировок. Другой распространенной причиной взаимоблокировок являются программы, которые не выполняют свою работу в соответствующих местах в логике.

EDIT - В вашем случае, вы утверждаете, вы вставляете их в пакетах по 500, но ваш начать/совершить это в начале и в конце все. Вам нужно поставить стартовый/исполняемый пакет и запустить/зафиксировать транзакцию внутри цикл. Вы держите в руках замки все записи вставляются

//data is of size say 10,000 i am dividing into 500 and inserting 
do { 
    sqlMapClient.startTransaction(); 
    sqlMapClient.startBatch(); 

    data500 = next 500 of data 
    getSqlMapClientTemplate().insert("insertData", data500); 

    sqlMapClient.executeBatch(); 
    sqlMapClient.commitTransaction(); 
}while(data500 is not empty) 

В качестве альтернативы, тупики «retryable» ошибки, если вы получаете в тупик, вы можете повторно запустить SQL и получить результаты (надеюсь, не тупик в этот раз).

+0

Отредактировано для включения «исправления» для вашего конкретного случая (вы запираете * все записи 10000 или около того) (плюс, вероятно, блокировка приподнятой таблицы) – rolfl

+0

, но я хочу, чтобы либо все 10000 было введено, либо ни один не должен вводиться. в этом случае, если вы фиксируете после каждой партии, то есть вероятность, что вставлены только некоторые из них. – dumper

+0

Очень реальная возможность заключается в том, что при запуске вставки записей вы блокируете строки/страницы, в которые вы вставляете. Но, в какой-то момент база данных решает, что у вас так много блокировок, что неэффективно отслеживать их по отдельности, а для того, чтобы эскалировать их в одну полную блокировку таблицы. Если какой-либо другой процесс изменял или даже мог выбирать из этой таблицы, тогда у вас есть условие взаимоблокировки. – rolfl

Смежные вопросы