一些澄清关于Spring @Transactional注释上的方法 [英] Some clarification about Spring @Transactional annotation on a method

查看:168
本文介绍了一些澄清关于Spring @Transactional注释上的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在春天的世界很新,我已经开发了使用Spring 3.2.1和Hibernate 4.1.9实现DAO一个简单的项目。该项目正常工作,但我对使用的一些疑虑的 @Transactional 在这个DAO的CRUD方法春季注释。

I am quite new in Spring world and I have developed a simple project that use Spring 3.2.1 and Hibernate 4.1.9 to implement a DAO. The project work correctly but I have some doubts about the use of @Transactional Spring annotation on CRUD method of this DAO.

这是实现我的项目的CRUD操作类的整个code:

This is the entire code of the class that implement the CRUD operation of my project:

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();
        }   

    }

}

好吧,你可以看到一些方法使用@Transactional注释annoted。

Ok,as you can see some methods are annoted using @Transactional annotation.

我在这里<一个看书的官方文档href=\"http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/transaction.html\">http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/transaction.html有关方法使用此批注的,它看到:使用@事务必须有事务语义的的方法annoted ,但它与事务语义意味着

I am readin the official documentation here http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/transaction.html about the use of this annotation on methods and it see that: A method annoted using @Transactional must have transactional semantics but what it means with transactional semantics?

这意味着,methos执行已被认为是一个事务处理的执行?因此,这意味着,该方法的操作必须被认为是一个单一的操作,这可能导致一个成功或失败,如果成功,操作的结果必须是永久的,而在出现故障的情况下,返回到之前的状态该交易的开始。

It means that the methos execution has to be considered as the execution of a transaction? So it means that the method operations have to be considered as a single operation that which may lead to a success or a failure, if successful, the results of operations has to be permanent, whereas in case of failure to return to the state prior to the start of the transaction.

这是利用意 @Transactional 上的一个方法的注释?

Is this the meaning of use @Transactional annotation on a method?

和究竟是什么意思的 readOnly的= FALSE addPerson的()方法的@Transactional注解的属性?这意味着,我也可以写一个记录在数据库中(而不是只读),或者什么?因为我明白,在默认情况下,使用@Transactional annotaion的读/写并不仅仅是读了交易definied的疑问是有关...
我也试着删除(只读= FALSE)属性,仍然运行良好(插入到数据库表中的新记录)

And what exactly mean the readOnly = false attribute in the @Transactional annotation of the addPerson() method? it mean that I can also write a record in the database (and not only read it) or what? The doubt is related because I have understand that, by default, a transaction definied using @Transactional annotaion is read/write and not just read... I have also try to delete the (readOnly = false) attribute and still work well (insert the new record in the database table)

以下DOUT是:为什么有些方法是使用@Transactional注解和一些其他的方法不是annoted是一个好pratcice到annote所有CRUD方法withd @Transactional?

The following dout is: "why some method are annoted using @Transactional annotation and some other methods not? is it a good pratcice to annote ALL CRUD method withd @Transactional?"

TNX

安德烈

推荐答案

首先,你不应该让DAO方法事务性的,但服务的方法。

First of all, you shouldn't make DAO methods transactional, but service methods.

二,使用事务是一种方法,让Spring启动和提交/回滚事务为您服务。所以,你不应该启动并承担自己的事务。

Second, using Transactional is a way to let Spring start and commit/rollback transactions for you. So you shouldn't start and commit transactions yourself.

第三:这个,如果你使用一个知道如何将Hibernate会话与交易相关联的事务管理器只会工作(通常是 HibernateTransactionManager的)。该会话工厂也应该由Spring处理,并在你的DAO由Spring注入。在DAO的code应该是这样的:

Third: this will only work if you use a transaction manager that knows how to associate a Hibernate session with the transaction (typically, a HibernateTransactionManager). The session factory should also be handled by Spring, and injected by Spring in your DAOs. The code of the DAO should look like this:

第四:你不应该打开一个新的会话,但得到的当前,由Spring关联到当前事务

Fourth: you should not open a new session, but get the current one, associated to the current transaction by Spring.

public class PersonDAOImpl implements PersonDAO {

    @Autowired
    private SessionFactory sessionFactory;

    public Integer addPerson(Person p) {
        Session session = sessionFactory.getCurrentSession();
        Integer personID = (Integer) session.save(p);
        return personID;
    }

    public Person getById(int id) {
        Session session = sessionFactory.getCurrentSession();
        Person retrievedPerson = (Person) session.get(Person.class, id);
        return retrievedPerson;
    }

    @SuppressWarnings("unchecked")
    public List<Person> getPersonsList() {
        Session session = sessionFactory.getCurrentSession();
        Criteria criteria = session.createCriteria(Person.class);
        return criteria.list();
    }

    public void delete(int id) {
        Session session = sessionFactory.getCurrentSession();
        Person personToDelete = getById(id);
        session.delete(personToDelete);
    }

    public void update(Person personToUpdate) {
        Session session = sessionFactory.getCurrentSession();
        session.update(personToUpdate);
    }
}

读<一个href=\"http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/htmlsingle/spring-framework-reference.html#orm-hibernate\">the文档以获取更多信息。

这篇关于一些澄清关于Spring @Transactional注释上的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆