Не удается получить откат транзакции Spring (Java + MySQL) - PullRequest
1 голос
/ 21 июня 2011

На прошлой неделе я наконец-то нашел способ использовать транзакции моего приложения.Я использую декларативные транзакции Spring, и я знаю, что сами транзакции работают, так как он заставил что-то с тысячами вставок перейти от 5-10 минут до 5-10 секунд внутри одной транзакции.База данных MySQL и все таблицы InnoDB.Поэтому я хотел, чтобы эта функция откатилась, если она не работает.По сути, это импорт файла XML и создание таблиц базы данных из XML.Поэтому, если что-то не получается, я не хочу частичную загрузку, иначе это будет непоследовательным.Я точно следовал документации Spring, и с тех пор как я запустил транзакции, я предполагаю, что общая конфигурация верна.

Вот соответствующая часть XML-файла:

<tx:advice id="txAdvice" transaction-manager="txManager">
  <tx:attributes>
    <tx:method name="get*" read-only="true"/>
    <tx:method name="uploadModelToProject" rollback-for="Throwable"/>
    <tx:method name="*"/>
  </tx:attributes>
</tx:advice>

Вот соответствующая часть Сервиса:

public interface ModelService {
    // interface to upload an LSI XML file of the  model into a project
    public Model uploadModelToProject(Project proj, String xmlFile);
}

UploadModelToProject вызывает метод в реализации SAX Parser, который затем реализует синтаксический анализ

public Model importModelToProject(Project proj, String xmlInputFileName) throws SAXException, IOException, ParserConfigurationException, ImportException {

    //get a factory
    SAXParserFactory spf = SAXParserFactory.newInstance();
    try {

        //get a new instance of parser 
        SAXParser sp = spf.newSAXParser();          

        //parse the file and also register this object for callbacks
        sp.parse(xmlInputFileName, this);                               

    } finally {
        newModel = null;
    }

    return newModel;

}

Я попытался использовать rollback-for = "Throwable", rollback-for = "Exception", rollback-for = "ImportException "(мое собственное исключение).Затем я вручную сгенерировал исключение в коде, и оно не сработало.Я не знаю, нужен ли мне какой-либо параметр распространения или какой-либо другой параметр.Не похоже, что я упускаю что-то очевидное.У кого-нибудь есть предложения?Все, что происходит, - это исключение, и все еще идет в базу данных.Я пропустил очевидный шаг?

Спасибо за любую помощь.

1 Ответ

2 голосов
/ 21 июня 2011

Я не получил ни клевок на предложения, но, наконец, понял это, поэтому решил опубликовать ответ на тот случай, если кто-нибудь еще попытается выяснить, что делать с откатом.Я включил уровень отладки для ведения журнала commons / log4j, чтобы я мог видеть, что происходит в среде Spring со всем.Вывод обильный, но полезный.

Оказалось, что мне не хватало понимания того, где Spring Framework перехватывает и перехватывает исключения в конфигурации, чтобы инициировать откат.

MyПервый набор кода, до того как я заполнил транзакцию, я перехватывал исключения из синтаксического анализа XML и просто возвращал нулевой указатель для обработки вызывающей стороной.Я не думал о том, где Spring будет обрабатывать исключение, поэтому меня не поразило, что если я поймаю исключения и не перебрасываю их, то Spring не знает.Моей следующей попыткой было передать все исключения, но нигде не обрабатывать их, ошибочно подумав, что Spring - это волшебство.Хорошей новостью было то, что транзакция была отменена, плохая новость состояла в том, что пользователю была возвращена страница с ошибкой.

Итак, мое "а-ха!"Был момент, когда я понял, что метод, указанный в конфигурации (т. е. в службе), должен быть тем, кто выдает исключение.Да, после осознания этого это кажется очевидным, но мне потребовалось пройти через это, чтобы понять это.Таким образом, в моем примере метод «uploadModelToProject» должен был перебросить исключения после того, как он его получил, и вызывающий объект для этого метода в службе должен вместо этого обработать исключение, что произошло бы сразу после того, как Spring перехватил его и выполнил откат.

Кроме того, вместо того, чтобы моя функция более низкого уровня в моем XML Importer выдавала все эти различные типы исключений, я создал свое собственное «ImportException», перехватил исключения и выбросил ImportException вверх.

Надеюсь, это кому-нибудь поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...