Весенняя декларативная сделка не откатывается - PullRequest
0 голосов
/ 30 декабря 2011

Я создал простое Spring-приложение для проверки основ Spring-декларативной транзакции. Согласно правилам декларативная транзакция должна откатываться в случае RuntimeException. Но это не откатывалось в моем случае.

Основной тестовый класс имеет код

public class SpringOraTest {
public static void main(String[] args) {
    ApplicationContext aplctx= new     
FileSystemXmlApplicationContext("src\\config\\SpringConfigForOra.xml");

    //Call to test Declarative Transaction with Annotation
TrxHandleAnnotated prxyobj=((TrxHandleAnnotated)aplctx.getBean("dbCommandAnnotated"));
prxyobj.doTask();
}
}

Класс TrxHandleAnnotated имеет код: -

@Transactional
public class TrxHandleAnnotated
public void doTask(){
 ApplicationContext aplctx= new  
 FileSystemXmlApplicationContext("src\\config\\SpringConfigForOra.xml");   
 JdbcTemplate jdbcTemplate= (JdbcTemplate)aplctx.getBean("jdbcTemplate");

 jdbcTemplate.update("insert into kau_emp values(4,'forthmulga' )");

 throw new RuntimeException();
}

И в конфигурационном XML была необходимая конфигурация.

Я ожидал, что транзакция будет отменена при возникновении исключения. Но это не было отменено, и запись передавалась в БД.

Даже после долгих поисков в интернете я не мог понять, почему он не получал отката.

Позже я понял, что в коде doTask () я снова создаю контекст и извлекаю наш экземпляр JdbcTemplate из нового контекста. Это было основной причиной проблемы.

Я изменил код так, что оба класса будут использовать некоторый контекст. И это сработало !!!

public class SpringOraTest {
public static ApplicationContext aplctx;
public static void main(String[] args) {
  aplctx= new FileSystemXmlApplicationContext("src\\config\\SpringConfigForOra.xml");

  //Call to test Declarative Transaction with Annotation
  TrxHandleAnnotated prxyobj=    
((TrxHandleAnnotated)aplctx.getBean("dbCommandAnnotated"));
prxyobj.doTask();
}

@Transactional
public class TrxHandleAnnotated
public void doTask(){

 JdbcTemplate jdbcTemplate=(JdbcTemplate)SpringOraTest.aplctx.getBean("jdbcTemplate");
 jdbcTemplate.update("insert into kau_emp values(4,'forthmulga' )");

 throw new RuntimeException();
}

Для меня это урок, что, если не требуется иное, все приложение должно использовать только один объект контекста.

Это будет звучать слишком очевидно для практикующих Spring, но новичок Spring, вроде меня, может делать такие глупые ошибки Мысль поделиться этим.

В этом конкретном случае вместо ручного создания JdbcTemplate лучше объявить его как переменную-член и использовать метод установки метода.

1 Ответ

0 голосов
/ 30 декабря 2011

используйте @TransactionConfiguration("name",ROLLBACK); //check syntax после @Transactional при объявлении TrxHandleAnnotated.см. эту ссылку для получения дополнительной информации о @Transcational и его использовании.

...