Sono abbastanza nuovo nel mondo Spring e ho sviluppato un progetto semplice che utilizza Spring 3.2.1 e Hibernate 4.1.9 per implementare un DAO. Il progetto funziona correttamente ma ho qualche dubbio sull'uso di @Transactional annotazione Spring sul metodo CRUD di questo DAO.Alcuni chiarimenti sull'annotazione Spring @Transactional su un metodo
Questo è l'intero codice della classe che implementa l'operazione CRUD del mio progetto:
package org.andrea.myexample.HibernateOnSpring.dao;
import java.util.List;
import org.andrea.myexample.HibernateOnSpring.entity.Person;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.springframework.transaction.annotation.Transactional;
public class PersonDAOImpl implements PersonDAO {
// Factory per la creazione delle sessioni di Hibernate:
private static SessionFactory sessionFactory;
// Metodo Setter per l'iniezione della dipendenza della SessionFactory:
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
/** CREATE CRUD Operation:
* Aggiunge un nuovo record rappresentato nella tabella rappresentato
* da un oggetto Person
*/
@Transactional(readOnly = false)
public Integer addPerson(Person p) {
System.out.println("Inside addPerson()");
Session session = sessionFactory.openSession();
Transaction tx = null;
Integer personID = null;
try {
tx = session.beginTransaction();
personID = (Integer) session.save(p);
tx.commit();
} catch (HibernateException e) {
if (tx != null)
tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
return personID;
}
// READ CRUD Operation (legge un singolo record avente uno specifico id):
public Person getById(int id) {
System.out.println("Inside getById()");
Session session = sessionFactory.openSession();
Transaction tx = null;
Person retrievedPerson = null;
try {
tx = session.beginTransaction();
retrievedPerson = (Person) session.get(Person.class, id);
tx.commit();
}catch (HibernateException e) {
if (tx != null)
tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
return retrievedPerson;
}
// READ CRUD Operation (recupera la lista di tutti i record nella tabella):
@SuppressWarnings("unchecked")
public List<Person> getPersonsList() {
System.out.println("Inside getPersonsList()");
Session session = sessionFactory.openSession();
Transaction tx = null;
List<Person> personList = null;
try {
tx = session.beginTransaction();
Criteria criteria = session.createCriteria(Person.class);
personList = criteria.list();
System.out.println("personList: " + personList);
tx.commit();
}catch (HibernateException e) {
if (tx != null)
tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
return personList;
}
// DELETE CRUD Operation (elimina un singolo record avente uno specifico id):
public void delete(int id) {
System.out.println("Inside delete()");
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Person personToDelete = getById(id);
session.delete(personToDelete);
tx.commit();
}catch (HibernateException e) {
if (tx != null)
tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
@Transactional
public void update(Person personToUpdate) {
System.out.println("Inside update()");
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
System.out.println("Insite update() method try");
tx = session.beginTransaction();
session.update(personToUpdate);
tx.commit();
}catch (HibernateException e) {
if (tx != null)
tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
}
Ok, come si può vedere alcuni metodi sono annotata con annotazioni @Transactional.
sto readin la documentazione ufficiale qui http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/transaction.html circa l'uso di questa annotazione sui metodi e vedere che: Metodo annotata utilizzando @Transactional deve avere semantica transazionale ma cosa vuol dire con semantica transazionale?
Significa che l'esecuzione del methos deve essere considerata come l'esecuzione di una transazione? Quindi significa che le operazioni del metodo devono essere considerate come una singola operazione che può portare a un successo o un fallimento, in caso di successo, i risultati delle operazioni devono essere permanenti, mentre in caso di mancato ritorno allo stato precedente l'inizio della transazione.
È questo il significato dell'uso annotazione @Transactional su un metodo?
E che cosa significa esattamente il readOnly = false attributo nella annotazioni @Transactional del addPerson() metodo? significa che posso anche scrivere un record nel database (e non solo leggerlo) o cosa? Il dubbio è correlato perché ho capito che, per impostazione predefinita, una transazione definita utilizzando @Transactional annotaion è lettura/scrittura e non solo lettura ... Ho anche provato a eliminare l'attributo (readOnly = false) e funziona ancora bene (inserisci il nuovo record nella tabella del database)
Il seguente dout è: "perché alcuni metodi vengono annotati usando l'annotazione @Transactional e altri metodi no? è un buon metodo per annotare il metodo ALL CRUD con @ Transazionale?"
Tnx
Andrea
Immagino che la configurazione della transazione non sia valida, dal momento che è possibile inserire qualcosa con una transazione di sola lettura. La mia ipotesi è che tu non usi affatto le transazioni. Vi preghiamo di fornirci ulteriori dettagli su come avete configurato il vostro ambiente di transazione (appcontext). Inoltre, non dichiarare le transazioni a livello di DAO, ma a livello aziendale (lì dove effettivamente si utilizzano i DAO). –