java 在 DAO 类中未找到标记为传播“强制”异常的事务的现有事务

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38734642/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 03:42:28  来源:igfitidea点击:

No existing transaction found for transaction marked with propagation 'mandatory' Exception in DAO classes

javaspringhibernatetransactions

提问by Nadeemm

I have an activity class that is annotated as a component that calls an action class:

我有一个活动类,它被注释为一个调用动作类的组件:

 @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = NonRetryableException.class)
 public ExecuteTemplateResponse executeTemplate(ExecuteTemplateRequest request)
 {
      actionExecutionContext = action.execute(actionExecutionContext);
 }

My action class is also annotated with @Component and has the following execute method:

我的动作类也用@Component 进行了注释,并具有以下执行方法:

@Transactional(propagation = Propagation.MANDATORY)
@Override
public ActionExecutionContext execute(ActionExecutionContext actionExecutionContext)
{
    iogl = ioglDao.create(iogl);
    return actionExecutionContext;
}

The ioglDao class is annotated as @Repository and has the following create method:

ioglDao 类被注解为@Repository 并具有以下创建方法:

@Transactional(propagation = Propagation.MANDATORY)
@Override
public InventoryOwnerGroupLocation create(InventoryOwnerGroupLocation iogl)
{
    // injected
    Session session = sessionFactory.getCurrentSession();

    session.save(iogl);

    return iogl;
}

I believe that the Transaction should propagate from the Service Layer to the dao class, but it seems it's not. I get the No existing transaction found for transaction marked with propagation 'mandatory' Exception.

我认为事务应该从服务层传播到 dao 类,但似乎不是。对于标记为传播“强制”异常的交易,我得到了 No existing transaction found。

Why isn't the transaction propagating to my DAO classes?

为什么事务没有传播到我的 DAO 类?

EDIT: added all of the activity class

编辑:添加了所有的活动类

@Service("FASelfServiceMappingService")
@Component
public class ExecuteTemplateActivity extends Activity
{
    private final static Logger logger = Logger.getLogger(ExecuteTemplateActivity.class);


// mapper framework to interact with DynamoDB database
private final DynamoDBMapper dynamoDBMapper;

// class to convert external models to internal models
private final InternalModelToDynamoDBModelConverter internalToDynamoDBConverter;
private final InternalModelToOracleModelConverter internalToOracleConverter;
private final CoralModelToInternalModelConverter coralToInternalConverter;

// class to generate list of actions
private final ActionGenerator actionGenerator;

// status constants
private static final String STATUS_COMPLETED = "COMPLETED";
private static final String STATUS_FAILED = "FAILED";

@Inject
public ExecuteTemplateActivity(InternalModelToDynamoDBModelConverter internalToDynamoDBConverter,
                               InternalModelToOracleModelConverter internalToOracleConverter,
                               CoralModelToInternalModelConverter coralToInternalConverter,
                               ActionGenerator actionGenerator,
                               DynamoDBMapper dynamoDBMapper)
{
    this.internalToDynamoDBConverter = internalToDynamoDBConverter;
    this.internalToOracleConverter = internalToOracleConverter;
    this.coralToInternalConverter = coralToInternalConverter;
    this.actionGenerator = actionGenerator;
    this.dynamoDBMapper = dynamoDBMapper;
}


@Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = NonRetryableException.class)
 @Operation("ExecuteTemplate")
 public ExecuteTemplateResponse executeTemplate(ExecuteTemplateRequest request) throws RetryableException, NonRetryableException
 {
     try
     {
         logger.info("Input given: " + request);

         // convert request input to an internal request
         Request internalRequest = coralToInternalConverter.coralRequestToInternal(request);
         logger.info("Successfully converted External Request to internal Request.");

         String templateName = getTemplateName(internalRequest);
         logger.info("Template Name extracted from the request: " + templateName);

         Template template = getTemplateFromDynamo(internalRequest, templateName);
         logger.info("Template read from dynamoDB table: " + template);

         // Generate a map from string to Action objects associated with the retrieved template
         List<Action> listOfActions = actionGenerator.generateActions(template.getActions());
         logger.info("Actions generated for template " + templateName + ": " + listOfActions);

         // Generate the action context for actions to pass to each other to keep track of state
         ActionExecutionContext actionExecutionContext = internalToOracleConverter.inputsToActionExecutionContext(internalRequest.getInputs());
        logger.info("Built ActionExecutionContext:" + actionExecutionContext);

         // execute the actions
         for (Action action : listOfActions)
         {
             actionExecutionContext = action.execute(actionExecutionContext);
         }
         logger.info("All actions executed successfully.");
         // request was completed successfully, create request in Request table
         String requestId = createRequestInDynamo(internalRequest, STATUS_COMPLETED);

         ExecuteTemplateResponse executeTemplateResponse = new ExecuteTemplateResponse();
         executeTemplateResponse.setRequestId(requestId);

         logger.info("Service call "+ this.getClass() +" succeeded.");
         return executeTemplateResponse;
         }
     catch (RetryableException re)
     {
         logger.error("Retryable Exception occurred in activity.", re);
         throw re;
     }
     catch (NonRetryableException nre)
     {
         logger.error("NonRetryable Exception occurred in activity.", nre);
         throw nre;
     }
     catch (Exception e)
     {
         logger.error("Unknown Exception occurred in activity.", e);
         throw new NonRetryableException("Unexpected error", e);
     }
 }

/**
 * extracts the templateName from the internalRequest
 * @param internalRequest internal model of the request
 * @return templateName
 */
private String getTemplateName(Request internalRequest)
{
    Validate.notNull(internalRequest, "internalRequest must not be null.");

    String templateName;
    try
    {
        // extract template name from request
        templateName = internalRequest.getTemplateName();
        Validate.notNull(templateName, "templateName must not be null.");
    }
    catch (IllegalArgumentException iae)
    {
        createRequestInDynamo(internalRequest, STATUS_FAILED);
        logger.error("Invalid input: templateName is null.");
        throw new NonRetryableException("Invalid input: templateName is null.", iae);
    }

    return templateName;
}

/**
 * Retrieves the template object associated with given templateName
 * @param internalRequest internal model of request
 * @param templateName name of template to retrieve
 * @return Template object
 */
private Template getTemplateFromDynamo(Request internalRequest, String templateName)
{
    Validate.notNull(internalRequest, "internalRequest must not be null.");
    Validate.notNull(templateName, "templateName must not be null.");

    Template template;
    try
    {
        // read the template with given template name from Templates table
        template = dynamoDBMapper.load(Template.class, templateName);
    }
    catch (DynamoDBMappingException ddbme)
    {
        createRequestInDynamo(internalRequest, STATUS_FAILED);
        logger.error("Reading template from dynamoDB table failed.", ddbme);
        throw new NonRetryableException("Incorrect class annotation or incompatible with class", ddbme);
    }
    catch (AmazonClientException ace)
    {
        createRequestInDynamo(internalRequest, STATUS_FAILED);
        logger.error("Reading template from dynamoDB table failed.", ace);
        throw new RetryableException("Error when loading template from dynamoDB", ace);
    }

    return template;
}

EDIT:

编辑:

Transaction Manager configuration:

事务管理器配置:

   <tx:annotation-driven transaction-manager="txManager"
                          mode="proxy" proxy-target-class='true' />

    <bean id="txManager"
          class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
        <property name="dataSource" ref="dataSource" />
    </bean>

采纳答案by Vladimiro Corsi

It is maybe a problem related to your Spring configuration. Did you follow the guide at http://docs.spring.io/autorepo/docs/spring/4.2.x/spring-framework-reference/html/transaction.html? Can you show how you configure Spring transaction management ?

这可能是与您的 Spring 配置相关的问题。您是否遵循http://docs.spring.io/autorepo/docs/spring/4.2.x/spring-framework-reference/html/transaction.html 上的指南?你能展示你如何配置 Spring 事务管理吗?