代码之家  ›  专栏  ›  技术社区  ›  user3094331

如果应用程序中抛出异常,Spring不会回滚事务

  •  0
  • user3094331  · 技术社区  · 6 年前

    我使用spring事务和在表中插入记录开发了应用程序。

    我在DAO类中显式抛出异常,但spring将记录插入表中,而不是回滚事务。

    我创建了以下两个应用程序。在案例1中,即使引发异常,也会将记录插入表中。但在案例2中,没有插入任何记录,spring成功回滚事务。你能解释一下这两种应用程序的区别吗。

    案例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);
    
        }
    }
    

    java

    @服务
    公共类ItemDao{
    
    @自动连线
    jdbc模板jdbc模板;
    
    
    无效插入(项目){
    
    更新(“插入到项_测试(itemno,itemtype,itemsize,itemname)值(?,,?,?)”,新对象[]{item.getItemNo(),item.getItemType(),item.getItemSize(),item.getItemName();
    INTA=2/0;
    }
    }
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   Ori Marko    6 年前

    注释你 ItemDao @Repository @Service

    您应该使用spring执行单元测试 上下文而不是main,例如使用TestNG:

    @ContextConfiguration(classes = {ConfigurationClass.class})
    @ActiveProfiles({"test"})
    public class TestItemDAO extends AbstractTransactionalTestNGSpringContextTests {
        @Autowired
        private ItemDao dao;
        @Test
        public void testItemDao() {
            dao.insert(item);
        }
    }
    
        2
  •  0
  •   Jonathan JOhx    6 年前

    如果删除try块,您将尝试处理异常,因此这就是RollbackException不剪切事务流的原因。