新事务中的异常导致父事务中的回滚

9w11ddsr  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(344)

我正在努力解决带有传播注解的方法的奇怪行为。需要\u new。
在方法placeorder()的主体中,最后一个操作是发送可能引发运行时异常的sms。
我不介意发送短信会引发异常,所以我不想在placeorder()中启动事务回滚。
方法sendsms()的传播需要\u new,所以据我所知,它不应该触发从挂起的事务回滚,只

@Component
public class OrderService {

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private ProductDao productDao;

    @Autowired
    private WarehouseService warehouseService;

    @Autowired
    private SmsClient smsClient;

    @Autowired
    private UserDao userDao;

    @Transactional
    @Override
    public void placeOrder(PlaceOrderRequest placeOrderRequest) {
        Product product = productDao.getById(placeOrderRequest.getProductId());
        WarehouseItem warehouseItem = warehouseService.getAvailable(product);
        Order order = orderDao.createNew();
        order.setProduct(product);
        order.setUser(user);
        smsClient.sendSms();
    }
}
@Component
public class SmsClient {

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void sendSms() {
        throwEx();
    }

    private void throwEx() throws SmsClientException {
        throw new SmsClientException();
    }
}

以下是transactionmanager的日志:

Creating new transaction with name [ai.optime.springmicroservicetemplate.domain.order.impl.DefaultOrderService.placeOrder]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
Opened new EntityManager [SessionImpl(1447696365<open>)] for JPA transaction
Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@25711903]
Executing DAO method 'getById' from class 'JpaBasedProductDao' with args {1}
Found thread-bound EntityManager [SessionImpl(1447696365<open>)] for JPA transaction
Participating in existing transaction
Executing DAO method 'getAvailable' from class 'JpaBasedWarehouseItemDao' with args {1}
HHH000397: Using ASTQueryTranslatorFactory
Found thread-bound EntityManager [SessionImpl(1447696365<open>)] for JPA transaction
Participating in existing transaction
Executing DAO method 'createNew' from class 'JpaBasedOrderDao' with args {}
Found thread-bound EntityManager [SessionImpl(1447696365<open>)] for JPA transaction
Participating in existing transaction
Executing DAO method 'getById' from class 'JpaBasedUserDao' with args {1}
Found thread-bound EntityManager [SessionImpl(1447696365<open>)] for JPA transaction
Participating in existing transaction
Found thread-bound EntityManager [SessionImpl(1447696365<open>)] for JPA transaction
Suspending current transaction, creating new transaction with name [ai.optime.springmicroservicetemplate.api.sms.SmsClient.sendSms]
Opened new EntityManager [SessionImpl(1649890926<open>)] for JPA transaction
Exposing JPA transaction as JDBC org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@6f98ca1d]
Initiating transaction rollback
Rolling back JPA transaction on EntityManager [SessionImpl(1649890926<open>)]
Closing JPA EntityManager [SessionImpl(1649890926<open>)] after transaction
Resuming suspended transaction after completion of inner transaction
Initiating transaction rollback
Rolling back JPA transaction on EntityManager [SessionImpl(1447696365<open>)]
Closing JPA EntityManager [SessionImpl(1447696365<open>)] after transaction
vm0i2vca

vm0i2vca1#

你的理解是错误的。您没有捕获 smsClient.sendSms() ,所以它是从 placeOrder() ,因此回滚为此方法启动的事务。
此外,制造 sendSms() 事务性没有多大意义,因为发送sms很可能不会与任何事务性资源进行交互。

相关问题