当前位置: 首页 > 知识库问答 >
问题:

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

刘野
2023-03-14

我正在与用propagation.requires_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

共有1个答案

司寇高洁
2023-03-14

你的理解是错误的。您没有捕捉到smsclient.sendsms()引发的异常,因此它是从placeorder()引发的,因此为该方法启动的事务将被回滚。

此外,使sendsms()成为事务性没有多大意义,因为发送SMS很可能不会与任何事务性资源交互。

 类似资料:
  • Spring 4.1.4 Hibernate 4.2.0 JDK 1.8 我的上下文:我有一个控制器调用-->Service-->调用Dao业务功能是删除(在1到许多DB关系中)一些子级,但不是所有子级。然后,在删除了一些子项之后,我尝试删除父项,然后我得到了java.sql.SqlIntegrityConstraintViolationException

  • 这很好,但并不总是在代码中抛出运行时异常。因此,我挖掘并发现如下所示的rollbackFor; 现在,我必须更改所有代码,以使用RollBackfor更改@Transactional。但是还有其他方法可以将所有@transaction advice属性更改为rollbackFor=exception.class吗?

  • 情景故事时间: 我“继承”了一个程序,一个用于访问数据库的相当简单的webservice。该程序在某个地方有一个缺陷:它试图更新一个没有更新授权的表。该程序只具有更新数据库队列的权限(Oracle),以保存谁访问了什么信息。这是不受欢迎的行为,现在我纠正了它。注意:这与这个问题本身无关,它只是导致我提出这个问题的原因。 该程序使用Spring+Hibernate来管理和访问数据和事务。 因为程序的

  • 我们使用CDI和CMT(容器管理事务)连接到web应用程序中的数据库,并标记从前端调用的方法,这些方法需要使用以下事务: 这将创建一个新的CDI事务,但是现在如果在执行此代码块或从此方法调用的任何其他代码块时发生异常,它将抛出错误消息: 有没有办法让CDI重新抛出嵌套错误,以便您可以轻松地调试回滚的真正原因是什么? (在 Java-EE7、Glassfish 4.0、JSF 2.2.2 上运行)

  • 我在tomcat服务器中使用具有多个数据源配置的JTA原子事务。有时我会遇到以下异常: JTA事务意外回滚(可能是由于超时);嵌套的异常是javax。交易回滚异常:事务被设置为仅回滚 出现这种异常的原因是什么?