9
votes

Spring3 'S @TransActional @scheduled non engagé à dB?

Ceci est mon 1ère fois essayant de Spring3's @scheduled, mais je n'ai trouvé que je ne peux pas m'engager à dB. Ceci est mon code:

@Service
public class ServiceImpl implements Service , Serializable
{
  @Inject 
  private Dao dao;

  @Inject
  @Qualifier("transactionManagerApp")
  private PlatformTransactionManager txMgrApp;

  @Override
  @Scheduled(cron="0 0 * * * ?")
  @Transactional(rollbackFor=Exception.class)
  public void hourly()
  {
    final TransactionTemplate txTemplateApp = new TransactionTemplate(txMgrApp);
    txTemplateApp.execute(new TransactionCallbackWithoutResult()
    {
      @Override
      protected void doInTransactionWithoutResult(TransactionStatus status)
      {
        //get xxx from dao
        dao.update(xxx);
      }
    });
  }
}


2 commentaires

Un peu hors sujet, mais vous n'avez pas besoin Rollbackfor pour @Transactional . La restauration est toujours faite implicitement pour les exceptions d'exécution.


J'ai essayé votre solution sale mais ça ne marche pas. une idée pourquoi?


3 Réponses :


0
votes

Lorsque vous utilisez une assistance axée sur l'annotation, cela ne fonctionne que sur les classes créées dans ce contexte. Mon pari est que ServiceImpl n'est créé dans le même contexte que votre gestionnaire de transactions (directement ou par analyse d'annotation).


4 commentaires

Merci, mais comment "appliquer" serviceImpl créé dans le même contexte que mon transactionManager?


Créez un haricot avec cette classe explicitement ou assurez-vous que votre étiquette de numérisation de composant est dans la même configuration ou la même configuration parent de votre gestionnaire de transactions.


Salut, pouvez-vous être plus précis? Je ne veux pas créer manuellement un service de service dans le fichier XML. Mais je ne suis pas clair sur "la balise de numérisation de composant est dans la même configuration ou parent de TXManager"? En effet, le "contexte: composant-balayage" et sont dans la même config! Mais pourquoi ça ne marche pas?


Maintenant, vous êtes sur quelque chose; Puisque vous définissez le composant-balayage et l'annotation, piloté dans le même fichier de configuration, je suis à perte. Je vais vous donner un +1 et j'espère que quelqu'un peut mieux ma réponse.



19
votes

Vous avez probablement compris cela ou déplacé (j'espère donc), mais pour le bénéfice des autres:

Le @Transactional Annotation indique le ressort d'envelopper votre haricot d'origine ServiceImpl avec un proxy dynamique qui implémente également le service '(par défaut printemps Proxies L'interface, pas la mise en œuvre). Ce proxy gérera de manière transparente la création et la validation de la transaction lorsque vous appelez horaire () sur le proxy . Cependant, si vous appelez horaire () directement sur votre implémentation (ce qui se passe ci-dessus), le proxy est contourné, il n'y a donc pas de transaction.

http://blog.springsource.org/2012/05/ 23 / compréhension-proxy-usage-in-printemps /

La solution est à

  1. Démarcate la transaction programmatique comme vous le faites dans votre solution "sale" (vous n'avez pas besoin que les annotations soient ceci).
  2. Assurez-vous que votre méthode @schedulée rend son appel à dao.update (xxx); via l'interface de service, pas directement sur votre implémentation (ainsi que dans le proxy). Fondamentalement, vous devez déplacer la méthode @scheduled à un autre haricon.

    J'espère que c'est assez clair!


2 commentaires

Donc, en ce qui concerne votre deuxième solution - que voulez-vous dire?


A fait quelle la deuxième solution dit. Déplacé les méthodes @@ transactionnel à un autre haricot injecté dans le haricot @@ planifié et les transactions sont maintenant vivantes! Sinon, j'ai continué à obtenir "Javax.Persistence.TransActionRequireitésException: pas d'entité transactionnel disponible"



0
votes

J'ai eu le même problème et après avoir passé du temps dessus, j'ai réalisé que j'avais une exception après l'appel de Dao.UnupDate () dans un code non apparenté qui n'a pas vérifié la valeur null - de sorte que cela a simplement cassé la transaction. Il n'y avait pas d'impression StackTrace car elle a été bien traitée au printemps (quelques blocs de capture). J'ai passé un moment sur ça. Ainsi, vérifiez simplement que votre méthode de transaction est terminée jusqu'à sa fin. J'espère que cela aidera quelqu'un.

Yosi Lev


0 commentaires