Quelques précisions à propos de Printemps @Transactional annotation sur une méthode
Je suis assez nouveau dans le Ressort du monde et j'ai développé un projet simple qui Ressort 3.2.1 et Hibernate 4.1.9 à mettre en œuvre un DAO. Le projet fonctionne correctement mais j'ai quelques doutes sur l'utilisation de @Transactional Printemps annotation sur CRUD méthode de DAO.
C'est le code complet de la classe qui implémente l'opération CRUD de mon projet:
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,comme vous pouvez le voir, certaines méthodes sont annotée avec @Transactional annotation.
Je suis readin la documentation officielle ici http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/transaction.html à propos de l'utilisation de cette annotation sur les méthodes et voir que: Une méthode annotée avec @Transactionnelle doit avoir la sémantique transactionnelle mais ce que cela signifie avec la sémantique transactionnelle?
Cela signifie que le methos exécution doit être considérée comme l'exécution d'une transaction? Donc, cela signifie que la méthode des opérations, doivent être considérées comme une seule opération, ce qui peut conduire à un succès ou un échec, en cas de succès, les résultats d'exploitation doit être permanente, tandis qu'en cas d'échec pour revenir à l'état avant le début de la transaction.
Est-ce le sens de l'utilisation @Transactional annotation sur une méthode?
Et ce que signifient exactement la readOnly = false attribut dans le @Transactional annotation de la addPerson() méthode? ça veut dire que je peux aussi écrire un enregistrement dans la base de données (et pas seulement lire) ou quoi? Le doute est lié parce que je dois comprendre que, par défaut, une transaction est défini à l'aide de @Transactional annotaion est de lecture/écriture et pas seulement lire...
J'ai également essayer de supprimer le (readOnly = false) attribut et encore bien travailler (insérer le nouvel enregistrement dans la table de base de données)
Suivantes dout est: "pourquoi certains méthode annotée avec @Transactional d'annotation et de certaines autres méthodes non? est-ce une bonne pratcice à annote TOUS CRUD méthode withd @Transactional?"
Tnx
Andrea
- Je suppose que votre configuration de la transaction n'est pas valide, puisque vous pouvez insérer quelque chose avec une transaction en lecture seule. Ma conjecture est que vous n'utilisez pas de transactions à tous. Merci de nous donner un peu plus en détail comment vous avez configuré votre transaction de l'environnement(appcontext). Aussi, ne pas déclarer vos transactions sur le DAO niveau, mais au niveau de l'entreprise(là où vous utilisez le DAOs).
Vous devez vous connecter pour publier un commentaire.
Tout d'abord, vous ne devriez pas faire de DAO méthodes transactionnelles, mais le service méthodes.
Seconde, à l'aide Transactionnelle est une façon de laisser le début du Printemps et commit/rollback transactions pour vous. Donc, vous ne devriez pas commencer et les transactions de validation vous-même.
Troisième: cela ne fonctionne que si vous utilisez un gestionnaire de transactions qui sait comment faire pour associer une session Hibernate avec la transaction (en général, un
HibernateTransactionManager
). La session de l'usine devrait être traitée par le Printemps, et injecté par le Printemps dans votre DAOs. Le code de la DAO devrait ressembler à ceci:Quatrième: vous ne devez pas ouvrir une nouvelle session, mais à obtenir l'actuel, associé à la transaction en cours par le Printemps.
Lire la documentation pour plus d'informations.
transferMoney()
est appelé. Ainsi, le Transactionnel annotation devrait être sur cetransferMoney()
méthode, et non pas sur les méthodes DAO il appelle en interne. Ceci est expliqué dans le Ressort de la documentation, BTW.@Transactional
est utilisé sur la méthode.Nous déclarer, au niveau de la méthode d'abord, il ouvre la transaction, effectuez l'opération et la clôture de la transaction.
Si une opération a échoué, il sera de restauration, si une opération est un succès, il sera automatiquement engagée
C'est sur
@Transactional
annotation enfin&court.