MongoDB.local SF, Jan 15: See the speaker lineup & ship your AI vision faster. Use WEB50 to save 50%
Find out more >
Docs 菜单
Docs 主页
/ /

事务和会话

在本指南中,您可以学习如何使用MongoDB Extension for Hibernate ORM 来执行事务。事务允许您运行一系列仅在提交整个ACID 事务后才更改数据的操作。

在MongoDB中,事务在逻辑会话中运行。会话是要按顺序运行的一组相关读取或写入操作。会话启用为一群组操作启用因果一致性,并允许您在符合ACID的ACID 事务中运行操作,该ACID 事务满足原子性、一致性、隔离性和持久性的预期。

Hibernate ORM 扩展支持以下用于管理会话和事务的 API:

  • Hibernate Session:允许您使用 org.hibernate.Transaction API 对数据库操作进行分组。要学习;了解详情,请参阅 Hibernate ORM 用户指南中的 Hibernate Transaction API

  • Jakarta Persistence EntityManager:指示 Hibernate ORM 在内部托管Session,并允许您使用 jakarta.persistence.EntityTransaction API 对数据库操作进行分组。要学习;了解更多信息,请参阅 Jakarta EE 文档中的jakarta.persistence包

The examples in this guide use the Movie entity, which represents the sample_mflix.movies collection from the Atlas sample datasets. The Movie entity has the following definition:

import com.mongodb.hibernate.annotations.ObjectIdGenerator;
import org.bson.types.ObjectId;
import java.util.List;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
@Entity
@Table(name = "movies")
public class Movie {
@Id
@ObjectIdGenerator
private ObjectId id;
private String title;
private String plot;
private int year;
private List<String> cast;
public Movie(String title, String plot, int year, List<String> cast) {
this.title = title;
this.plot = plot;
this.year = year;
this.cast = cast;
}
public Movie() {
}
public ObjectId getId() {
return id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getPlot() {
return plot;
}
public void setPlot(String plot) {
this.plot = plot;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public List<String> getCast() {
return cast;
}
public void setCast(List<String> cast) {
this.cast = cast;
}
}

要学习如何创建Java应用程序以使用MongoDB Extension for Hibernate ORM与此MongoDB示例集合交互,请参阅 入门教程

要与MongoDB数据交互,您必须在会话中运行所有数据库操作。本节介绍如何通过以下方式管理数据库会话:

提示

在使用 Session 之前,您必须创建一个配置 SessionFactoryHibernateUtil.java文件。要学习;了解更多信息,请参阅入门教程中的配置应用程序步骤。

要启动 Hibernate Session,请执行以下步骤:

  1. 使用 getSessionFactory() 方法从 HibernateUtil 实用程序类中检索 SessionFactorySessionFactory 存储您的MongoDB连接配置,并且可以打开新的数据库会话。

  2. 通过在 SessionFactory实例上调用 openSession() 方法来创建 Session

  3. 运行数据库操作后,对这两个实例使用 close() 方法关闭 SessionFactorySession

The following example runs a database query in a session and retrieves a document that has a title value of "Erin Brockovich" from the sample_mflix.movies collection:

var sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
var movie = session.createQuery("from Movie where title = :t", Movie.class)
.setParameter("t", "Erin Brockovich")
.getSingleResult();
System.out.println("Title: " + movie.getTitle() + ", Year: " + movie.getYear());
session.close();
sf.close();
Title: Erin Brockovich, Year: 2000

还可以使用 Java 的 try-with-resources 声明 来简化会话管理逻辑并自动关闭会话,如以下代码所示:

var sf = HibernateUtil.getSessionFactory();
try (Session session = sf.openSession()) {
var movie = session.createQuery("from Movie where title = :t", Movie.class)
.setParameter("t", "Erin Brockovich")
.getSingleResult();
System.out.println("Title: " + movie.getTitle() + ", Year: " + movie.getYear());
}
sf.close();

提示

在使用 EntityManager 之前,您必须创建一个声明持久性单元的 persistence.xml文件。要学习;了解更多信息,请参阅 Hibernate ORM 文档中的使用 JPA 标准 API 的教程

要启动 Jakarta Persistence API (JPA) EntityManager,请执行以下步骤:

  1. 通过调用 createEntityManagerFactory() 方法从 persistence.xml文件创建 EntityManagerFactory,该方法会在内部创建 SessionFactory

  2. 通过对 EntityManagerFactory实例调用 createEntityManager() 方法来创建 EntityManager,这会在内部创建 Session

  3. 运行数据库操作后,在 EntityManagerFactoryEntityManager 实例上调用 close() 方法以关闭这两个实例。

The following example runs a database query in an entity manager and retrieves documents that have a year value of 1929 from the sample_mflix.movies collection:

// Replace <persistence unit> with the name of your persistence unit in the persistence.xml file
EntityManagerFactory emf = Persistence.createEntityManagerFactory("<persistence unit>");
EntityManager entityManager = emf.createEntityManager();
var results = entityManager.createQuery("select m from Movie m where m.year = :y", Movie.class)
.setParameter("y", 1929)
.getResultList();
results.forEach(movie -> System.out.println(movie.getTitle()));
entityManager.close();
emf.close();
The Broadway Melody
Queen Kelly
Asphalt
Hallelujah
Disraeli
Applause
Lambchops

在 Jakarta Persistence v3.1 或更高版本中,您可以使用 Java 的 try-with-resources 声明 自动关闭 EntityManager,如 Hibernate 会话 部分所示。

要修改MongoDB数据,必须在ACID 事务中运行所有写入操作。本节介绍如何通过以下方式托管ACID 事务:

要启动 Hibernate Transaction,请在 Session实例上调用 beginTransaction() 方法。运行操作并使用 persist() 方法在会话中注册更改后,通过调用 commit() 方法提交ACID 事务。

以下示例使用ACID 事务对 sample_mflix.movies集合执行以下操作:

  • 创建新的 Movie 实体并将其作为文档插入到集合

  • 更新 title 值为 "Black Swan" 的文档的 cast字段

突出显示的行开始并提交ACID 事务:

var sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
Transaction tx = session.beginTransaction();
var newMovie = new Movie();
newMovie.setTitle("Lady Bird");
newMovie.setYear(2017);
session.persist(newMovie);
var movie = session.createQuery("from Movie where title = :t", Movie.class)
.setParameter("t", "Black Swan")
.getSingleResult();
var currentCast = new ArrayList<>(movie.getCast());
currentCast.add("Winona Ryder");
movie.setCast(currentCast);
tx.commit();
session.close();
sf.close();

要创建 JPA EntityTransaction,请对 EntityManager 调用 getTransaction() 方法。此方法检索一个 EntityTransaction,其中包装了根本的Hibernate Transaction。然后,调用 begin() 方法启动ACID 事务。运行操作并使用 persist() 方法向实体管理器注册更改后,通过调用 commit() 方法提交事务。

以下示例使用 EntityTransactionsample_mflix.movies集合中删除一个文档,然后插入一个标题值为 "The Favourite" 的新文档。突出显示的行开始并提交ACID 事务:

// Replace <persistence unit> with the name of your persistence unit in the persistence.xml file
EntityManagerFactory emf = Persistence.createEntityManagerFactory("<persistence unit>");
EntityManager entityManager = emf.createEntityManager();
entityManager.getTransaction().begin();
// Your ObjectId value might differ
Movie movieToDelete = entityManager.find(Movie.class, new ObjectId("573a1399f29313caabcedc5d"));
entityManager.remove(movieToDelete);
var addMovie = new Movie();
addMovie.setTitle("The Favourite");
addMovie.setYear(2018);
entityManager.persist(addMovie);
entityManager.getTransaction().commit();
entityManager.close();
emf.close();

要放弃ACID 事务中的所有数据更改,请对 Hibernate Transaction 或 JPA EntityTransaction 调用 rollback() 方法。调用此方法后,Hibernate ORM 将恢复未提交的更改并清除持久化上下文。

The following example rolls back the transaction if the code throws an error. Select the Hibernate Transaction or JPA EntityTransaction tab to see the corresponding code:

Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Movie movie = new Movie();
movie.setTitle("Control Alt Delete");
session.persist(movie);
tx.commit();
} catch (Exception e) {
if (tx != null) {
tx.rollback();
}
e.printStackTrace();
} finally {
session.close();
}
EntityManager entityManager = emf.createEntityManager();
EntityTransaction tx = entityManager.getTransaction();
try {
tx.begin();
Movie movie = new Movie();
movie.setTitle("Control Alt Delete");
entityManager.persist(movie);
tx.commit();
} catch (Exception e) {
if (tx != null && tx.isActive()) {
tx.rollback();
}
e.printStackTrace();
} finally {
entityManager.close();
}

要学习;了解有关会话和实体经理人的更多信息,请参阅 Hibernate ORM 文档中的持久化上下文。

要学习;了解有关事务的更多信息,请参阅 事务 Hibernate ORM 文档中的事务。

后退

执行原生查询

在此页面上