關於拋異常事務回滾的測試

TestController.java 代碼以下***:
/**
 * 測試異常回滾.
 * @return
 */
@RequestMapping(value = "/testExceptionRollBack")
@ResponseBody
public String testExceptionRollBack() {
    List<String> idList = Lists.newLinkedList();
    idList.add("1111111111");
    idList.add("2222222222");
    idList.add("3333333333");
    try {
        return orderService.testUpdateStatus(idList);
    } catch (Exception e) {
        logger.error("執行失敗", e);
        return "執行失敗";
    }
}

TestService.java 代碼以下***:
public String testUpdateStatus(List<String> idList) throws Exception {
    List<Order> orderList = orderDao.listByIds(idList);
    if (!orderList.isEmpty()) {
        int index = 1;
        for (Order order : orderList) {
            try {
                requestDataService.insert("URL",
                        "ttt", "測試異步", "測試成功", Common.FLAG_Y, 1, order.getOrderCode());
                if ("PO1805060174".equals(order.getOrderCode())) {
                    throw new RuntimeException("測試此單據拋異常事務回滾");
                } else {
                    TestOccupation occu = new TestOccupation();
                    occu.setStorageAreaId(order.getStorageAreaId());
                    occu.setCommodityCode("TT" + index);
                    occu.setDocumentCode(order.getOrderCode());
                    occu.setOccupiedQty(order.getTotalQty());
                    occu.setCreateDate(new Date());
                    occu.setCreateUserId(OpmUser.INTERFACE_USER_ID);
                    occu.setDocumentId(order.getOrderId());
                    occu.setDocumentDetailId(order.getOrderId() + "" + index);
                    testOccupationDao.add(newDocumentOccupation);
                }
                index++;
            } catch (Exception e) {
                logger.error("執行異常", e);
            }
        }
    }
    return null;
}

結論: 通過測試發現, 程序在運行的時候拋出一個運行時異常, 事務並不會回滾, 請求信息依然保存到了DB.
接下來看另外一種現象, TestController仍是不變, 將TestService的
【throw new RuntimeException("測試此單據拋異常事務回滾");】 修改以下:
【entityService.testException("PO1805060174");】
EntityService.java 代碼以下***:
public void testException(String code) throws Exception {
    if (TextUtils.isNotEmpty(code)) {
        throw new RuntimeException("測試在另外一個service發出一個異常");
    }
}

結論: 通過測試發現, 程序運行中執行到拋異常後整個事務會回滾, 請求信息都沒有保存到DB中, 
這就意味着調用的子方法在另一個service中的時候拋異常即使捕獲了仍然會拋異常.接下來再將
requestDataRecordService的方法 insert 加個異步的註解, 代碼以下***:

@Async
public void insert(***) {
}

結論: 通過再次測試得出, requestDataService.insert 存入到DB中了,可是inventoryDocumentOccupationDao.add 沒有存入DB, 
證實加了異步方法的註解標識後, 此方法不會被回滾.接下來再將EntityService代碼修改以下***:

public void testException(String code) throws Exception {
    try {
        if (TextUtils.isNotEmpty(code)) {
            throw new RuntimeException("測試在另外一個service發出一個異常");
        }
    } catch (Exception e) {
        logger.error("測試異常", e);
    }
}

結論: 再繼續測試, 發如今【原始拋異常的地方進行捕獲】後事務就不會回滾, 請求信息被存入了DB中. 

備註: 測試的項目使用的框架: SpringMVC + Spring + mybatis
相關文章
相關標籤/搜索