gpt4 book ai didi

java - 关于方法上的 Spring @Transactional 注释的一些说明

转载 作者:IT老高 更新时间:2023-10-28 13:04:40 26 4
gpt4 key购买 nike

我是 Spring 世界的新手,我开发了一个使用 Spring 3.2.1 和 Hibernate 4.1.9 来实现 DAO 的简单项目。该项目工作正常,但我对在此 DAO 的 CRUD 方法上使用 @Transactional Spring 注释有一些疑问。

这是实现我项目的CRUD操作的类的全部代码:

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注解来注解的。

我在这里阅读官方文档 http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/transaction.html关于在方法上使用此注解,它看到:使用 @Transactional 注释的方法必须具有事务语义,但它对事务语义意味着什么?

意思是methos的执行必须被认为是事务的执行?所以这意味着方法操作必须被视为可能导致成功或失败的单个操作,如果成功,则操作结果必须是永久的,而如果失败则返回到之前的状态交易的开始。

这就是在方法上使用@Transactional注解的意思吗?

addPerson() 方法的@Transactional 注释中的readOnly = false 属性究竟是什么意思?这意味着我也可以在数据库中写入一条记录(而不仅仅是读取它)还是什么?这个疑问是相关的,因为我知道,默认情况下,使用 @Transactional 注释定义的事务是 read/write 而不仅仅是读取...我也尝试删除 (readOnly = false) 属性并且仍然可以正常工作(在数据库表中插入新记录)

下面的问题是:“为什么有些方法使用@Transactional 注释而其他一些方法没有?用@Transactional 注释所有CRUD 方法是一个好习惯吗?”

Tnx

安德烈亚

最佳答案

首先,您不应该将 DAO 方法设为事务性方法,而应将其设为服务方法。

其次,使用 Transactional 是一种让 Spring 为您启动和提交/回滚事务的方法。所以你不应该自己开始和提交事务。

第三:这只有在您使用知道如何将 Hibernate session 与事务关联的事务管理器(通常是 HibernateTransactionManager)时才有效。 session 工厂也应该由 Spring 处理,并由 Spring 在您的 DAO 中注入(inject)。 DAO 的代码应该是这样的:

第四:你不应该打开一个新的 session ,而是获取当前 session ,通过 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 documentation了解更多信息。

关于java - 关于方法上的 Spring @Transactional 注释的一些说明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15300483/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com