Spring не откатит транзакцию, если в приложении возникнет исключение - PullRequest
0 голосов
/ 28 ноября 2018

Я разработал приложение, используя пружинные транзакции и вставив записи в таблицу.

Я явно выбрасываю исключение в классе DAO, но Spring вставляет запись в таблицу, а не откатывает транзакцию.

Я создал два приложения, как показано ниже.В случае 1 запись вставляется в таблицу, хотя генерируется исключение.Но в случае 2 никакая запись не вставлена, и пружинный откат успешно завершен.Можете ли вы объяснить мне разницу между этими двумя приложениями.

Случай 1:

Item.java

public class Item {

    int itemNo;
    String itemName;
    String itemType;
    String itemSize;
    public int getItemNo() {
        return itemNo;
    }
    public void setItemNo(int itemNo) {
        this.itemNo = itemNo;
    }
    public String getItemName() {
        return itemName;
    }
    public void setItemName(String itemName) {
        this.itemName = itemName;
    }
    public String getItemType() {
        return itemType;
    }
    public void setItemType(String itemType) {
        this.itemType = itemType;
    }
    public String getItemSize() {
        return itemSize;
    }
    public void setItemSize(String itemSize) {
        this.itemSize = itemSize;
    }
}

ItemDao

@Service
public class ItemDao {

    @Autowired
    JdbcTemplate jdbcTemplate ;


    void insert(Item item){

        jdbcTemplate.update("insert into item_test(itemno, itemtype,itemsize,itemname) values (?,?,?,?)", new Object[]{item.getItemNo(),item.getItemType(),item.getItemSize(),item.getItemName()});
        int a=2/0;
    }
}

ItemService.java

@Service
public class ItemService {
    @Autowired
    ItemDao itemDao;    


    @Transactional
    public void insert(Item item){
        try{
            itemDao.insert(item);
        }
        catch(Exception e){
            e.printStackTrace();
        }
    }
}

Test.java

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        ApplicationContext ct = new ClassPathXmlApplicationContext("spring.xml");
        ItemService itemService = ct.getBean("itemService", ItemService.class);

        Item item = new Item();
        item.setItemNo(1234);
        item.setItemName("sofa");
        item.setItemSize("4");
        item.setItemType("furniture");
        itemService.insert(item);
    }

}

spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd   http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
    <!-- Enable Annotation based Declarative Transaction Management -->
    <tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager" />
    <context:component-scan base-package="com.spring.springtransaction" />
    <!-- Creating TransactionManager Bean, since JDBC we are creating of type 
        DataSourceTransactionManager -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
    <!-- MySQL DB DataSource -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="oracle.jdbc.OracleDriver" />
        <property name="url" value="jdbc:oracle:thin:@locahost:1521:xe)))" />
        <property name="username" value="system" />
        <property name="password" value="system" />
    </bean>
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource" />
    </bean>
    <bean id="itemService" class="com.spring.springtransaction.ItemService" />
</beans>

Случай 2:

ItemService.java

@Service
public class ItemService {
    @Autowired
    ItemDao itemDao;

    @Autowired
    ItemManger itemManger;

    @Transactional
    public void insert(Item item){
        try{
            itemManger.insert(item);
        }
        catch(Exception e){
            e.printStackTrace();
        }
    }
}

ItemManger.java

@Service
public class ItemManger {

    @Autowired
    ItemDao itemDao;


    @Transactional
    public void insert(Item item){

        itemDao.insert(item);

    }
}

ItemDao.java

@Service
public class ItemDao {

    @Autowired
    JdbcTemplate jdbcTemplate ;


    void insert(Item item){

        jdbcTemplate.update("insert into item_test(itemno, itemtype,itemsize,itemname) values (?,?,?,?)", new Object[]{item.getItemNo(),item.getItemType(),item.getItemSize(),item.getItemName()});
        int a=2/0;
    }
}

Ответы [ 2 ]

0 голосов
/ 28 ноября 2018

Удалите блок try, вы пытаетесь обработать исключение, поэтому это причина, по которой RollbackException не обрезает поток транзакций.

0 голосов
/ 28 ноября 2018

Аннотировать вас ItemDao как @Repository вместо @Service

Вы должны выполнить модульный тест с пружиной Транзакционный контекст вместо основного, например, используя TestNG:

@ContextConfiguration(classes = {ConfigurationClass.class})
@ActiveProfiles({"test"})
public class TestItemDAO extends AbstractTransactionalTestNGSpringContextTests {
    @Autowired
    private ItemDao dao;
    @Test
    public void testItemDao() {
        dao.insert(item);
    }
}
...