Domanda

Voglio sapere che cosa realmente accade quando si annota un metodo con @Transactional? Certo, lo so che la primavera andrà a capo quel metodo in una transazione.

Ma, ho i seguenti dubbi:

  1. Ho sentito che la primavera crea un classe proxy ? Qualcuno può spiegare questo in modo più profondità . Che risiede in realtà in quella classe proxy? Cosa accade alla classe reale? E come posso vedere Classe proxy creato Spring
  2. ho letto anche in documenti di primavera che:
  

Nota: Poiché questo meccanismo si basa sui proxy, unico metodo 'esterno' chiamate in arrivo attraverso il proxy verrà intercettato . Ciò significa che 'auto-invocazione', cioè un metodo all'interno l'oggetto di destinazione chiamando un altro metodo dell'oggetto target, non porterà a una transazione reale in fase di esecuzione, anche se il metodo invocato è contrassegnato con @Transactional!

Fonte: http://static.springsource.org/ molla / docs / 2.0.x / riferimento / transaction.html

Perché solo le chiamate di metodo esterni saranno sotto transazione e non i metodi di auto-invocazione?

È stato utile?

Soluzione

Questo è un grande argomento. Il dottore di riferimento Primavera dedica più capitoli ad esso. Vi consiglio di leggere quelle sul Aspect-Oriented Programming e Le operazioni , come il supporto delle transazioni dichiarativa di Spring usa AOP al suo fondazione.

Ma a un livello molto alto, Primavera crea proxy per le classi che dichiarano @Transactional sulla classe stessa o sui membri. La delega è per lo più invisibile in fase di esecuzione. Esso fornisce un modo per Spring iniettare comportamenti prima, dopo, o intorno chiamate di metodo in oggetto da proxy. gestione delle transazioni è solo un esempio dei comportamenti che possono essere agganciati in. I controlli di sicurezza sono un altro. E si può fornire il proprio, anche per cose come la registrazione. Così, quando si annota un metodo con @Transactional , Primavera crea dinamicamente un proxy che implementa la stessa interfaccia (s) come la classe che stai annotazione. E quando i clienti effettuare chiamate nel vostro oggetto, le chiamate vengono intercettati e comportamenti iniettato attraverso il meccanismo proxy.

Le operazioni in opera EJB Allo stesso modo, tra l'altro.

Come si osserva, attraverso, il meccanismo di delega funziona solo quando le chiamate arrivano da qualche oggetto esterno. Quando si effettua una chiamata interna all'interno dell'oggetto, si sta davvero facendo una chiamata attraverso il " questo " di riferimento, che bypassa il proxy. Ci sono modi di lavorare intorno a quel problema, comunque. Spiego un approccio questo post nel forum in cui io uso un BeanFactoryPostProcessor per iniettare un'istanza del proxy in classi "auto-riferimento" in fase di esecuzione. Risparmio questo riferimento a una variabile membro denominata " me ". Poi, se ho bisogno di fare chiamate interne che richiedono un cambiamento di stato della transazione del filo, ho diretto la chiamata attraverso il proxy (ad esempio " me.someMethod () ".) Il post forum spiega in più dettaglio. Si noti che il BeanFactoryPostProcessor codice sarebbe un po 'diverso ora, come è stato scritto indietro nei tempi primavera 1.x. Ma spero che vi dà un'idea. Ho una versione aggiornata che probabilmente potrei mettere a disposizione.

Altri suggerimenti

Quando Primavera carica le definizioni di fagioli, ed è stato configurato per cercare le annotazioni @Transactional, si creerà questi oggetti proxy intorno alla vostra fagiolo attuale. Questi oggetti proxy sono istanze di classi che sono auto-generata in fase di esecuzione. Il comportamento di default di questi delega oggetti quando un metodo viene invocato è solo quello di richiamare lo stesso metodo sul fagiolo "target" (vale a dire il bean).

Tuttavia, i proxy possono anche essere forniti con intercettori, e quando sono presenti questi intercettori saranno invocati dal proxy prima che richiama il metodo vostro obiettivo del bean. Per i semi bersaglio annotati con @Transactional, Spring creerà un TransactionInterceptor, e passarlo all'oggetto proxy generato. Così, quando si chiama il metodo dal codice del client, si sta chiamando il metodo sull'oggetto proxy, che prima invoca il TransactionInterceptor (che inizia una transazione), che a sua volta richiama il metodo sul fagiolo di destinazione. Quando l'invocazione termina, il TransactionInterceptor impegna / ripristina la transazione. E 'trasparente per il codice del client.

Per quanto riguarda la cosa "metodo esterno", se il bean richiama uno dei propri metodi, allora non sarà così facendo tramite il proxy. Ricordate, Primavera avvolge il bean nel proxy, il bean non ha alcuna conoscenza di esso. Solo le chiamate da "fuori" il bean passare attraverso il proxy.

Fa che aiutano?

Come persona visiva, mi piace pesare in un diagramma di sequenza del proxy pattern. Se non sai come leggere le frecce, ho letto il primo uno come questo:. Client esegue Proxy.method()

  1. Il cliente chiama un metodo sul bersaglio dal suo punto di vista, ed è stato intercettato in silenzio dal proxy
  2. Se un prima aspetto è definito, il proxy lo esegue
  3. Quindi, viene eseguito il metodo effettivo (target)
  4. Dopo-ritorno e dopo-lancio sono aspetti che sono opzionali eseguita dopo il metodo restituisce e / o se il metodo genera un eccezione
  5. Dopo di che, il proxy esegue l'aspetto dopo (se definito)
  6. Infine il proxy ritorna al client chiamante

Proxy modello Sequence Diagram (Mi è stato permesso di inviare la foto a condizione che ho menzionato le sue origini. Autore: Noel Vaes, sito web: www.noelvaes.eu)

La risposta più semplice è, a seconda di quale metodo si dichiara @Transactional il confine della transazione inizia e finisce quando il metodo di confine completa.

Se si utilizza chiamata JPA poi tutti i commit sono con in questo limite di transazione. Diciamo che si sta salvando Entity1, entity2 e entity3. Ora, mentre il risparmio entity3 un'eccezione verificare poi come enitiy1 e entity2 realizzato negli stessi dell'operazione l'Entity1 e entity2 saranno rollback con entity3.

di transazione: (entity1.save, entity2.save, entity3.save). Ogni eccezione si tradurrà in rollback di tutte le transazioni JPA con DB. Internamente JPA transazione vengono utilizzati entro la primavera.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top