вопрос
В ходе стресс-теста было обнаружено, что генерировался один и тот же порядковый номер.По анализу журнала было установлено, что select... for update не блокирует данные определенной строки, в результате чего порядковые номера повторяются.
Проверить
- Очень важно определить мутективный механизм SELECT... для обновления, данные строки должны быть заблокированы, другие SELECT... для обновления/обновления/удаления и другие SQL должны ждать блокировки для выполнения последующих операций.
- Сначала сомневаетесь, работает ли транзакция, используйте TransactionSynchronizationManager#getCurrentTransactionName, чтобы распечатать текущую транзакцию, и результат оказываетсяnull!!!Никакие транзакции, естественно, не будут взаимоисключающими, что может объяснить, почему генерируются повторяющиеся порядковые номера.
- Остальное, почему аннотация @Transactional явно добавляется, но транзакция не запускается.
- Проверьте код с проблемой. Проблемный код показан ниже. Это шаблон проектирования цепочки ответственности. Для любого узла цепочки ответственности сначала вызовитеdoProcessВыполнить логику самого подкласса, в случае успеха выполнить следующийsuccУзел, ошибка отчета, выполните следующийfailУзел до конца цепочки ответственности.
- нашел декларативную транзакциюdoProcessметод, онprocessиспользуется вthis.doProcessВызывается, мы все знаем, что транзакция Spring AOP должна использоваться, чтобы вступить в силу.другой объект.методдействителен, поэтому @Transactional не работает. Короче говоря, его нельзя использовать втот же классВызов метода с @Transactional с помощью метода без @Transactional
public abstract class BaseController {
private ScBaseController succNext = null;
private ScBaseController failNext = null;
public DataMessage process(DataMessage msg) throws ScBaseException {
DataMessage respMsg = this.doProcess(msg);
// 执行成功
if (ExecuteResultEnum.SUCCESS.equals(respMsg.getExecuteResult())) {
if (this.succNext != null) {
return this.succNext.process(respMsg);
} else {
return respMsg;
}
}
// 执行失败
else {
if (this.failNext != null) {
return this.failNext.process(respMsg);
} else {
return respMsg;
}
}
}
@Transactional // 这里的事务注解没有作用
public abstract DataMessage doProcess(DataMessage msg);
урок
-
Я читал много статей о том, что вы не можететот же классМетод без @Transactional используется в методе для вызова метода с @Transactional. Это определяется механизмом динамического АОП Spring. Этот урок нужно иметь в виду. Что касается того, почему динамический АОП такой, я объясню. подробно позже, если я напишу статью по этому поводу.
-
К счастью, мы обнаружили, что в ходе стресс-теста этот вопрос не вызвал ошибку.Некоторые проблемы не могут сделать несколько транзакций ясными, должны быть в состоянии проверить надежность системы в высокопараллельном тесте под высоким давлением.