问题描述
我在春天的世界很新,我已经开发了使用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.
我在这里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);
}
}
读the文档以获取更多信息。
这篇关于一些澄清关于Spring @Transactional注释上的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!