Spring循环体内的事务控制

Spring的事务隔离级别等不介绍了
在Spring的事务应用中,有时候需要用到循环体内单个控制事务,每一次循环与上次循环不交叉影响,单独提交或回滚,不影响整个循环体。

//开启事务

@Transactional(propagation = Propagation.REQUIRED)
public Result generateMeteringMonthlyBill() {
        Result ret = Result.success();
        GenerateContractBillService  billService = BillServiceGenerateFactory.getMeteringMonthlyBillService();
        List contractList = billService.getContractList();
        for(ServiceContractDTO dto:contractList){
            try {
                            //单独事务,每次回滚或提交不影响,调用方法的事务(generateMeteringMonthlyBill),也不影响下次循环的事务
                        billService.processContract(dto,endDate);

            } catch (Exception e) {
                //调用日志服务,单独事务
                sysLogService.addSysLog("", "", dto.getServicectrCode(), "T03", "", "计量月结合同生成账单失败-异常:" + e.getMessage());
                e.printStackTrace();
            }
        }
    return ret;
}

由于Spring的事务传播级别是类级别,如果类中的一个方法使用的某一个类型的事务,那么整个类的事务都是一种事务,而且回滚级别也是类级别的,也就是在同一个类中A方法调用B方法,A方法使用REQUIRED,B方法使用的REQUIRES_NEW,在B方法抛出RUNTIMEException,在A方法中捕获,回滚点不是到B方法,而是B方法不进行回滚,因为Spring事务认定级别以类为单位,所以只有退出类的调用时,对会触发事务的提交或回滚。所以即使在同个类中调用不同的事务级别,也是没有意义的。因为Spring 事务代理类执行方法的切入点是类:
Spring 代理执行方法(1):

protected Object invokeWithinTransaction(Method method, Class targetClass, final InvocationCallback invocation)
            throws Throwable {

        // If the transaction attribute is null, the method is non-transactional.
        final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
        final PlatformTransactionManager tm = determineTransactionManager(txAttr);
        **final String joinpointIdentification = methodIdentification(method, targetClass);**
执行(2) targetClass不会为NULL:
protected String methodIdentification(Method method, Class targetClass) {
        return (targetClass != null ? targetClass : method.getDeclaringClass()).getName() + "." + method.getName();
    }

鉴于这个原因,解决方法需要在循环体内的进行单独事务控制的方法,放在一个A类中,包含循环体的方法放在一个B类中,这个A类中方法使用REQUIRES_NEW事务控制,B类使用REQUIRED事务控制。这样就解决了循环体内的相互影响

你可能感兴趣的:(Spring)