Alguns esclarecimentos sobre a anotação Spring @Transactional em um método

Eu sou bastante novo no mundo da Primavera e desenvolvi um projeto simples que usa o Spring 3.2.1 e o Hibernate 4.1.9 para implementar um DAO. O projeto funciona corretamente, mas tenho algumas dúvidas sobre o uso de@Transactional Anotação de mola no método CRUD deste DAO.

Este é o código inteiro da classe que implementa a operação CRUD do meu projeto:

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, como você pode ver, alguns métodos são anotados usando a anotação @Transactional.

Estou lendo a documentação oficial aquihttp://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/transaction.html sobre o uso desta anotação em métodos e veja que:Um método anotado usando @Transactional deve ter semântica transacional mas o que isso significa com a semântica transacional?

Isso significa que a execução do methos deve ser considerada como a execução de uma transação? Portanto, significa que as operações do método têm que ser consideradas como uma única operação que pode levar a um sucesso ou a uma falha, se bem-sucedidas, os resultados das operações devem ser permanentes, enquanto no caso de falha retornar ao estado antes de o início da transação.

É este o significado de uso@Transactional anotação em um método?

E o que exatamente significa oreadOnly = false atributo na anotação @Transactional doaddPerson () método? isso significa que eu também posso escrever um registro no banco de dados (e não apenas lê-lo) ou o quê? A dúvida está relacionada porque eu entendi que, por padrão, uma transação definida usando a anotação @Transactional éler escrever e não apenas ler ... Eu também tentei apagar o(readOnly = false) atributo e ainda funciona bem (insira o novo registro na tabela do banco de dados)

A seguinte dout é: "por que alguns métodos são anotados usando anotação @Transactional e alguns outros métodos não? É um bom pratcice anotar o método ALL CRUD withd @Transactional?"

Tnx

Andrea

questionAnswers(2)

yourAnswerToTheQuestion