当前位置: 首页 > news >正文

Springboot MongoDB 事务

目录

1. 事务和TransactionTemplate

2. 事务和MongoTransactionManager

3. 响应式事务

4. 事务和TransactionalOperator

5. 事务和ReactiveMongoTransactionManager

6. 事务内部的特殊行为


从版本4开始,MongoDB支持 事务。事务是建立在 会话之上的,因此,需要一个活跃的 ClientSession。

除非你在你的应用程序上下文中指定一个 MongoTransactionManager,否则事务支持是 DISABLED(禁用的)。你可以使用 setSessionSynchronization(ALWAYS) 来参与正在进行的非本地 MongoDB 事务。

为了获得对事务的完全程序化控制,你可能想在 MongoOperations 上使用会话回调。

下面的例子显示了在一个 SessionCallback 中的程序化事务控制。

Example 124. 程序性事务

ClientSession session = client.startSession(options);                   template.withSession(session).execute(action -> {session.startTransaction();                                     try {Step step = // ...;action.insert(step);process(step);action.update(Step.class).apply(Update.set("state", // ...session.commitTransaction();                                } catch (RuntimeException e) {session.abortTransaction();                                 }}, ClientSession::close)                                            

获得一个新的 ClientSession。

开始事务。

如果一切按预期进行,就提交修改。

出现意外,所以要回滚一切。

完成后不要忘记关闭会话。

前面的例子让你完全控制事务行为,同时在回调中使用会话范围的 MongoOperations 实例,以确保会话被传递给每个服务器调用。为了避免这种方法带来的一些开销,你可以使用 TransactionTemplate 来消除手动事务流的一些噪音。

1. 事务和TransactionTemplate

Spring Data MongoDB事务支持一个 TransactionTemplate。下面的例子展示了如何创建和使用 TransactionTemplate。

Example 125. 事务和 TransactionTemplate

template.setSessionSynchronization(ALWAYS);                                     // ...TransactionTemplate txTemplate = new TransactionTemplate(anyTxManager);         txTemplate.execute(new TransactionCallbackWithoutResult() {@Overrideprotected void doInTransactionWithoutResult(TransactionStatus status) {     Step step = // ...;template.insert(step);process(step);template.update(Step.class).apply(Update.set("state", // ...};
});

在 Template API 配置中启用事务同步。

使用提供的 PlatformTransactionManager 创建 TransactionTemplate。

在回调中,ClientSession 和事务已经被注册。

在运行期间改变 MongoTemplate 的状态(就像你可能认为在前面列表的第1项中可能发生的那样)会导致线程和可见性问题。

2. 事务和MongoTransactionManager

MongoTransactionManager 是通往众所周知的Spring事务支持的网关。它可以让应用程序使用 Spring的事务托管功能。MongoTransactionManager 将一个 ClientSession 绑定到线程上。MongoTemplate 会检测会话,并相应地对这些与事务相关的资源进行操作。MongoTemplate 也可以参与到其他正在进行的事务中。下面的例子展示了如何用 MongoTransactionManager 创建和使用事务。

Example 126. 事务和 MongoTransactionManager

@Configuration
static class Config extends AbstractMongoClientConfiguration {@BeanMongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {  return new MongoTransactionManager(dbFactory);}// ...
}@Component
public class StateService {@Transactionalvoid someBusinessFunction(Step step) {                                        template.insert(step);process(step);template.update(Step.class).apply(Update.set("state", // ...};
});

在应用 application context 中注册 MongoTransactionManager。

将方法标记为事务性。

@Transactional(readOnly = true) 建议 MongoTransactionManager 也启动一个事务,将 ClientSession 添加到发出的请求中。

3. 响应式事务

与支持响应式 ClientSession 一样,ReactiveMongoTemplate 提供了专门的方法,用于在事务中进行操作,而不必担心根据操作结果提交或停止操作。

除非你在你的 application context 中指定一个 ReactiveMongoTransactionManager,否则事务支持是 DISABLED(禁用的)。你可以使用 setSessionSynchronization(ALWAYS) 来参与正在进行的非本地MongoDB事务。

使用普通的MongoDB响应式驱动API,在一个事务性流程中的 delete 可能看起来像这样。

Example 127. 原生驱动的支持

Mono<DeleteResult> result = Mono.from(client.startSession())                                                             .flatMap(session -> {session.startTransaction();                                                          return Mono.from(collection.deleteMany(session, ...))                                .onErrorResume(e -> Mono.from(session.abortTransaction()).then(Mono.error(e)))   .flatMap(val -> Mono.from(session.commitTransaction()).then(Mono.just(val)))     .doFinally(signal -> session.close());                                           });

首先,我们显然需要启动session。

一旦我们有了 ClientSession,就开始事务。

通过向操作传递 ClientSession,在事务中进行操作。

如果操作异常完成,我们需要停止事务并保留错误。

当然,也可以在成功的情况下提交更改。仍然保留操作结果。

最后,我们需要确保关闭会话。

上述操作的罪魁祸首是在保留 main flow DeleteResult,而不是通过 commitTransaction() 或 abortTransaction() 发布的事务结果,这导致了相当复杂的设置。

4. 事务和TransactionalOperator

Spring Data MongoDB事务支持一个 TransactionalOperator。下面的例子展示了如何创建和使用一个 TransactionalOperator。

Example 128. 事务和 TransactionalOperator

template.setSessionSynchronization(ALWAYS);                                          // ...TransactionalOperator rxtx = TransactionalOperator.create(anyTxManager,new DefaultTransactionDefinition());              Step step = // ...;
template.insert(step);Mono<Void> process(step).then(template.update(Step.class).apply(Update.set("state", …)).as(rxtx::transactional)                                                         .then();

为事务性参与启用事务同步。

使用提供的 ReactiveTransactionManager 创建 TransactionalOperator。

TransactionalOperator.transactional(…​) 为所有上游操作提供事务管理。

5. 事务和ReactiveMongoTransactionManager

ReactiveMongoTransactionManager 是通往众所周知的 Spring事务支持 的网关。它允许应用程序利用Spring的管理事务功能。ReactiveMongoTransactionManager 将 ClientSession 绑定到 subscriber Context。ReactiveMongoTemplate 会检测会话,并对这些与事务相关的资源进行相应操作。 ReactiveMongoTemplate 也可以参与其他正在进行的事务。下面的例子展示了如何用 ReactiveMongoTransactionManager 创建和使用事务。

Example 129. 事务和 ReactiveMongoTransactionManager

@Configuration
public class Config extends AbstractReactiveMongoConfiguration {@BeanReactiveMongoTransactionManager transactionManager(ReactiveMongoDatabaseFactory factory) {  return new ReactiveMongoTransactionManager(factory);}// ...
}@Service
public class StateService {@TransactionalMono<UpdateResult> someBusinessFunction(Step step) {                                  return template.insert(step).then(process(step)).then(template.update(Step.class).apply(Update.set("state", …));};
});

在application context中注册 ReactiveMongoTransactionManager。

将方法标记为事务性的。

@Transactional(readOnly = true) 建议 ReactiveMongoTransactionManager 也启动一个事务,将 ClientSession 添加到发出的请求中。

6. 事务内部的特殊行为

在事务内部,MongoDB服务器有一个稍微不同的行为。

Connection Settings

MongoDB驱动提供了一个专门的副本集名称配置选项,使驱动进入自动检测模式。这个选项有助于识别主要的副本集节点和事务中的命令路由。

确保在MongoDB的URI中添加 replicaSet。请参考 连接字符串选项 以了解更多细节。

Collection Operations

MongoDB不支持集合操作,例如在事务中创建集合。这也会影响到第一次使用时发生的即时集合创建。因此,请确保所有需要的结构都已到位。

Transient Errors

MongoDB可以为在事务性操作中出现的错误添加特殊标签。这些标签可能表示暂时性的故障,这些故障可能通过重试操作而消失。我们强烈推荐 Spring Retry 用于这些目的。然而,我们可以覆写 MongoTransactionManager#doCommit(MongoTransactionObject),以实现MongoDB参考手册中所述的重试提交操作行为。

Count

MongoDB的 count 操作是基于集合统计的,可能无法反映事务中的实际情况。当在一个多文档事务中发出 count 命令时,服务器会响应 error 50851。一旦 MongoTemplate 检测到一个活动的事务,所有暴露的 count() 方法都会被转换,并使用 $match 和 $count 操作符委托给聚合框架,保留 Query 设置,如 collation。

在 aggregation count helper 中使用 geo 命令时,有一些限制。以下运算符不能使用,必须用不同的运算符代替。

  • $where → $expr
  • $near → $geoWithin with $center
  • $nearSphere → $geoWithin with $centerSphere

使用 Criteria.near(…​) 和 Criteria.nearSphere(…​) 的查询必须改写为 Criteria.within(…​) 各自的 Criteria.withinSphere(…​)。同样适用于 repository 查询方法中的 near 查询关键字,必须改为 within。也请参见MongoDB JIRA ticket DRIVERS-518 以进一步参考。

下面的片段显示了会话绑定闭包内的 count 用法。

session.startTransaction();template.withSession(session).execute(action -> {action.count(query(where("state").is("active")), Step.class)...

上面的片段具体化为以下命令。

db.collection.aggregate([{ $match: { state: "active" } },{ $count: "totalEntityCount" }]
)

而不是。

db.collection.find( { state: "active" } ).count()

相关文章:

Springboot MongoDB 事务

目录 1. 事务和TransactionTemplate 2. 事务和MongoTransactionManager 3. 响应式事务 4. 事务和TransactionalOperator 5. 事务和ReactiveMongoTransactionManager 6. 事务内部的特殊行为 从版本4开始&#xff0c;MongoDB支持 事务。事务是建立在 会话之上的&#xff0c…...

SAP自建表日志

文章目录 1.在表里加上日志记录字段1.1 加入日志结构1.2 在代码中调用记录日志通用函数1.3 在SM30里面记录日志1.4 缺点1.5 优点 2.表技术设置-日志数据更改2.1 RZ10或者RZ11修改系统参数2.2 设置表的属性2.3 查询日志2.4 缺点2.5 优点 3 SCDO文档对象3.1 勾选相应字段-数据元素…...

ansible-kubeadm在线安装单masterk8s v1.19-v1.20版本

ansible可以安装的KS8版本如下&#xff1a; [rootk8s-master01 ~]# yum list kubectl --showduplicates | sort -r kubectl.x86_64 1.20.0-0 kubernetes kubectl.x86_64 1.20.0-0 …...

mongodb docker 及常用命令

MongoDB属于非关系型数据库&#xff0c;它是由C编写的分布式文档数据库。内部使用类似于Json的bson二进制格式。 中文手册 https://www.w3cschool.cn/mongodb/ 安装 https://www.mongodb.com/try/download/community 二进制安装可见另一篇&#xff1a; centos7 mongodb 4.0.28…...

最新版本mac版Idea 激活Jerbel实现热部署

1.环境准备 1.安装docker desktop 客户端创建本地服务 2.创建guid 3.随便准备一个正确格式的邮箱 2.具体操作 1.通过提供的镜像直接搭建本地服务 docker pull qierkang/golang-reverseproxy docker run -d -p 8888:8888 qierkang/golang-reverseproxy2.guid 通过如下网址直…...

基于Ubuntu22.04部署bcache模式ceph

作者&#xff1a;吴业亮 博客&#xff1a;wuyeliang.blog.csdn.net 将Bcache集成到Ceph OSD后端可以带来一些优点和潜在的缺点。以下是它们的一些方面&#xff1a; 优点&#xff1a; 提高性能&#xff1a;BCache作为SSD缓存设备&#xff0c;可以提供更快的数据读取和写入速度…...

根据URL批量下载文件并压缩成zip文件

根据url批量下载图片或者视频&#xff0c;只需要将图片的url和名称放到数组对象即可&#xff0c;例如&#xff1a; let fileArr [{fvUrl:https://image.xuboren.com/image/2023/07/26/1410829074764cdbaa4314a084eb749e.jpg,fvName: 图片名称},{fvUrl:https://image.xuboren.…...

机器学习笔记之优化算法(六)线搜索方法(步长角度;非精确搜索;Glodstein Condition)

机器学习笔记之优化算法——线搜索方法[步长角度&#xff0c;非精确搜索&#xff0c;Glodstein Condition] 引言回顾&#xff1a; Armijo Condition \text{Armijo Condition} Armijo Condition关于 Armijo Condition \text{Armijo Condition} Armijo Condition的弊端 Glodstein…...

Ant Design Pro 封装网络请求

可以直接在antdPro项目的app.tsx文件中对request进行运行时配置&#xff0c;并且该配置会直接透传到umi-request的全局配置。后续直接从umi中引入request或者useRequest直接使用&#xff0c;可以说是非常方便。文档可查看&#xff1a;umi.js 具体配置代码&#xff1a; import…...

命令模式——请求发送者与接收者解耦

1、简介 1.1、概述 在软件开发中&#xff0c;经常需要向某些对象发送请求&#xff08;调用其中的某个或某些方法&#xff09;&#xff0c;但是并不知道请求的接收者是谁&#xff0c;也不知道被请求的操作是哪个。此时&#xff0c;特别希望能够以一种松耦合的方式来设计软件&a…...

css 利用模糊属性 制作水滴

<style>.box {background-color: #111;height: 100vh;display: flex;justify-content: center;align-items: center;/* 对比度*/filter: contrast(20);}.drop {width: 150px;height: 159px;border-radius: 50%;background-color: #fff;position: absolute;/* 模糊 */filt…...

怎么才能提升自己工作能力?

表现最好的员工通常是获得加薪和工作晋升的人。您可以采取某些措施来提高您的工作绩效&#xff0c;并帮助您的主管将您视为他们最好的员工之一。在本文中&#xff0c;我们列出了 12 个技巧&#xff0c;可以立即提高您的工作绩效。 什么是工作绩效&#xff1f; 工作绩效是指您…...

Android Framework 之 Zygote

Android Zygote Android Zygote 是 Android 操作系统中一个关键的系统服务&#xff0c;它在系统启动时加载&#xff0c;为应用程序的运行提供了一种快速且资源高效的方式。 Zygote 的主要作用如下&#xff1a; 预加载共享库和类&#xff1a;Zygote 启动时&#xff0c;会预先加…...

二叉树的中序遍历 LeetCode热题100

题目 给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。 思路 递归&#xff0c;按左中右的顺序添加节点。 利用栈先进后出的特性模拟递归。 代码 /**递归写法* Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left…...

IOS + Appium自动化教程

前言 项目闲置下来了&#xff0c;终于抽空有时间搞自动化了&#xff0c;看了下网上的教程基本通篇都是android自动化的介绍 &#xff0c;ios自动化方面的内容网上简介的少之可怜。由于本人对ios自动化也是第一次做&#xff0c;甚至对苹果电脑的使用都不太熟悉&#xff0c;花了大…...

100个精选Python实战项目案例,在线无偿分享

前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 随着 Python 语言的流行&#xff0c;越来越多的人加入到了 Python 的大家庭中。 为什么这么多人学 Python &#xff1f; 我要喊出那句话了&#xff1a;“人生苦短&#xff0c;我用 Python&#xff01;”&#xff0c; 正是…...

JSON语法

目录 一、JSON 语法规则 二、JSON 的两种结构&#xff1a; 三、JSON 名称/值对 JSON 值 JSON 数字 JSON 对象 JSON 数组 JSON 布尔值 JSON null 四、JSON 使用 JavaScript 语法 JSON 语法是 JavaScript 语法的子集。 一、JSON 语法规则 JSON 语法是 JavaScript 对象…...

PostMan+Jmeter+QTP工具介绍及安装

目录 一、PostMan介绍​编辑 二、下载安装 三、Postman与Jmeter的区别 一、开发语言区别&#xff1a; 二、使用范围区别&#xff1a; 三、使用区别&#xff1a; 四、Jmeter安装 附一个详细的Jmeter按照新手使用教程&#xff0c;感谢作者&#xff0c;亲测有效。 五、Jme…...

2023电赛E题视觉部分

该部分主要要完成正方形区域的识别&#xff0c;并返回对应的坐标&#xff0c;但是由于距离1m&#xff0c;过远。因此需要引入图像增强&#xff0c;下面代码完成基本流程测试&#xff0c;仅供参考&#xff1a; import sensor import image import time # 初始化摄像头 senso…...

算法工程师岗位面试必备,讲透深度学习面试题,详解人工智能生成式任务与AI大模型面试题

DeepLearning-Interview-Awesome-2024 算法工程师岗位面试必备&#xff0c;讲透深度学习面试题&#xff0c;详解人工智能生成式任务与AI大模型面试题 实时更新题解链接&#xff1a;https://github.com/315386775/DeepLearing-Interview-Awesome-2024 记得点个关注&#xff0…...

JVM基础篇-虚拟机栈

JVM基础篇-虚拟机栈 定义 Java Virtual Machine Stacks &#xff08;Java 虚拟机栈&#xff09; 每个线程运行时所需要的内存&#xff0c;称为虚拟机栈每个栈由多个栈帧&#xff08;Frame&#xff09;组成&#xff0c;对应着每次方法调用时所占用的内存每个线程只能有一个活动…...

KepwareEX配置API REST接口

服务端Kepware设置 API允许连接设置 创建通道 请求地址(POST)&#xff1a; https://<主机名_或_ip>:<端口>/config/v1/project/channels 以下示例使用postman工具访问API创建了一个名为Channel1 的通道&#xff0c;其使用在本地主机运行的服务器中的Simulator …...

【python】python求解矩阵的转置(详细讲解)

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…...

Mr. Cappuccino的第56杯咖啡——Mybatis拦截器

Mybatis拦截器 概述应用场景项目结构实现分页查询其它拦截器的使用 概述 Mybatis允许使用者在映射语句执行过程中的某一些指定的节点进行拦截调用&#xff0c;通过织入拦截器&#xff0c;在不同节点修改一些执行过程中的关键属性&#xff0c;从而影响SQL的生成、执行和返回结果…...

容器化安装环境EFK搭建

容器化安装环境 Docker中安装并启动ElasticSearch 前置配置 第一步&#xff1a;在宿主机上执行echo “net.ipv4.ip_forward1” >>/usr/lib/sysctl.d/00-system.conf 2.第二步&#xff1a;重启network和docker服务 [rootlocalhost /]# systemctl restart network &&…...

基于 Debian GNU/Linux 12 “书虫 “的Neptune 8.0 “Juna “来了

导读Neptune Linux 发行版背后的团队发布了 Neptune 8.0&#xff0c;作为这个基于 Debian 的 GNU/Linux 发行版的重大更新&#xff0c;它围绕最新的 KDE Plasma 桌面环境构建。 Neptune 8.0 被命名为 “Juna”&#xff0c;是在Neptune 7.5 发布 11 个月后发布的&#xff0c;也是…...

GDAL C++ API 学习之路 (4) Spatial Reference System篇 OGRSpatialReference类

class OGRSpatialReference #include <ogr_spatialref.h> OGRSpatialReference 是 GDAL/OGR 库中的一个重要类&#xff0c;用于管理和操作地理空间数据的空间参考系统&#xff08;Spatial Reference System&#xff0c;SRS&#xff09;。它提供了一系列功能&…...

RS232转Profinet网关rs232转网口需要如何设置

大家好&#xff0c;今天我要给大家带来一个很有意思的案例分享。你们猜猜&#xff0c;这回我们要用捷米的一款神奇的网关JM-RS485/232-PN做什么呢&#xff1f;没错&#xff0c;我们要把一台扫码枪设备通过这个RS232转PROFINET网关&#xff0c;接入到一台西门子S7-1200PLC的Prof…...

LaTex的下载与安装超详细windows版

1.LaTex的下载 &#xff08;texlive下载TexStudio下载&#xff09; &#xff08;1&#xff09;texlive下载&#xff1a; 这里清华镜像下载 &#xff08;2&#xff09;TexStudio下载&#xff1a; 点这里下载镜像 可以根据不同的系统选择不同的版本 2 .LaTex的安装 &#…...

MySQL | 存储过程快速入门

文章目录 一、概述1.1 MySQL存储过程和函数的概念1.2 优势和适用场景 二、存储过程基础2.1 存储过程与传统SQL查询的区别2.2 创建和调用存储过程创建存储过程调用存储过程 2.3 参数传递与返回值创建带有输出参数的存储过程调用带有输出参数的存储过程 2.4 流程控制语句IF语句WH…...