2016-08-03 3 views
2

Ich habe eine Aktivitätsklasse gefunden markiert, die als Komponente bezeichnet ist, die eine Aktion Klasse aufruft:Keine vorhandene Transaktion für Transaktion mit Ausbreitungs ‚zwingend‘ Exception in DAO-Klassen

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

Meine Action-Klasse mit ebenfalls kommentiert @Component und hat das folgende Verfahren auszuführen:

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

ioglDao die Klasse wird als @Repository annotiert und hat das Verfahren folgendes erzeugen:

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

    session.save(iogl); 

    return iogl; 
} 

Ich glaube, dass die Transaktion von der Service-Schicht auf die Dao-Klasse propagieren sollte, aber es scheint, dass es nicht ist. Ich bekomme die No existing transaction found für Transaktion markiert mit Propagation "obligatorisch" Exception.

Warum verbreitet sich die Transaktion nicht in meine DAO-Klassen?

EDIT: die gesamte Aktivität Klasse hinzugefügt

@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-Konfiguration:

<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> 
+0

Kannst du mehr von deiner Aktivitätsklasse zeigen (besonders den Teil, in den du deine Action-Klasse spritzt)? – dunni

+0

Und auch der Teil, wo Sie die Methode executeTemplate aufrufen. Nennen Sie es von einer anderen Klasse oder von innerhalb Ihrer Aktivitätsklasse? – dunni

+0

Alle meiner Aktivitätsklasse hinzugefügt. Ich teste die Aktivitätsklasse in einem Komponententest und rufe executeTemplate aus einem Komponententest auf. – Nadeemm

Antwort

0

Es ist vielleicht ein Problem mit Ihrer Spring-Konfiguration verwendet. Hast du den Guide unter verfolgt? Können Sie zeigen, wie Sie das Spring-Transaktionsmanagement konfigurieren?

+0

Ja, ich folgte dem Führer. Ich habe die Frage mit meinem Spring-Transaktionsmanagement aktualisiert. – Nadeemm

+0

Danke. Noch einige Fragen: funktioniert die Injektion von sessionFactory in der Aktivitätsklasse? Ist das Komponentenscannen korrekt konfiguriert? ()? Da Sie bereits "@Service" haben, ist die Annotation "@Component" für die Aktivitätsklasse erforderlich? –

+0

Ich habe keine Injektion von sessionFactory in der Aktivitätsklasse versucht, da sie dort nicht benötigt wird. Es wird direkt in die DAO-Klassen injiziert. Soll ich das versuchen? Ja, das Scannen von Komponenten ist korrekt konfiguriert. Die Annotation @Service für die Aktivitätsklasse stammt aus einem anderen internen Framework, nicht aus dem Frühling. – Nadeemm

Verwandte Themen