Spring 事务(编程式事务、声明式事务@Transactional、事务隔离级别、事务传播机制)
文章目录
- 1. 事务的定义
- 2. Spring 中事务的实现
- 2.1 MySQL 中使用事务
- 2.2 Spring 中编程式事务的实现
- 2.3 Spring 中声明式事务
- 2.3.1 声明式事务的实现 @Transactional
- 2.3.2 @Transactional 作用域
- 2.3.3@Transactional 参数设置
- 2.3.4 @Transactional 异常情况
- 2.3.5 @Transactional 工作原理
- 3. 事务隔离级别
- 3.1 事务特性
- 3.2 Spring 中设置事务隔离级别
- 4. Spring 事务传播机制
- 4.1 事务传播机制是什么
- 4.2 为什么需要事务传播机制
- 4.3 事务传播机制有哪些
- 4.4 Spring 事务传播机制使用
- 4.4.1 支持当前事务(REQUIRED 默认)
- 4.4.2 不支持当前事务(REQUIRES_NEW)
- 4.4.3 不支持当前事务(NOT_SUPPORTED)
- 4.4.4 NESTED 嵌套事务
- 4.4.5 嵌套事务和加入事务的区别
本篇重点总结:
- 在 Spring 项目中使用事务,有两种方式:编程式手动操作和声明式自动提交,声明式自动提交使用最多,只需要在方法上添加注解 @Transactional
- 设置事务的隔离级别 @Transactional(isolation = Isolation.SERIALIZABLE),Spring 中的事务隔离级别有5种
- 设置事务的传播机制 @Transactional(propagation = Propagation.REQUIRED),Spring 中的事务传播级别有 7 种
1. 事务的定义
事务定义:将一组操作封装成一个执行单元(封装到一起),要么全部成功,要么全部失败
那么为什么要用事务呢
比如两个银行账户之间的转账操作:
- 第一步操作:A 账户 -100 元
- 第二步操作:B 账户 +100 元
如果没有事务。第一步执行成功了,第二步执行失败了,那么 A 账号就丢失了 100 元,而如果使用事务就可以解决这个问题,让这一组操作要么一起成功,要么一起失败
2. Spring 中事务的实现
Sping 中事务的操作用两种:
- 编程式事务(手写代码操作事务)
- 声明式事务(利用注解自动开启和提交事务)
2.1 MySQL 中使用事务
MySQL 中事务有 3 个重要的操作:开启事务、提交事务、回滚事务,它们对应的操作命令如下
-- 开启事务
start transaction;-- 业务执⾏
-- 提交事务
commit;
-- 回滚事务
rollback;
2.2 Spring 中编程式事务的实现
Spring 中手动操作事务和 MySQL操作事务类似,也是有 3 个重要操作
- 开启事务(获取事务)
- 提交事务
- 回滚事务
Spring Boot 内置了两个对象,DataSourceTransactionManager (事务管理器)用来获取事务(开启事务)、提交或回滚事务的,而 TransactionDefinition 是事务的属性,在获取事务的时候需要将 TransactionDefinition 传递进去从而获得一个事务 TransactionStatus 对象
@RestController
public class UserController {@Autowiredprivate UserService userService;@Autowiredprivate DataSourceTransactionManager transactionManager;@Autowiredprivate TransactionDefinition transactionDefinition;// 在此方法中使用编程式的事物@RequestMapping("/add")public int add(UserInfo userInfo) {// 非空效验【验证用户名和密码不为空】if(userInfo==null || !StringUtils.hasLength(userInfo.getUsername())|| !StringUtils.hasLength(userInfo.getPassword())) {return 0;}// 开启事务(获取事务)TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition);int result = userService.add(userInfo);System.out.println("add 受影响的行数:" + result);// 提交事务transactionManager.commit(transactionStatus);
// // 回滚事务
// transactionManager.rollback(transactionStatus);return result;}
}
运行程序分别查看提交事务和回滚事务的效果
2.3 Spring 中声明式事务
2.3.1 声明式事务的实现 @Transactional
声明式事务的实现,只需要在方法上添加 @Transactional 注解就可以实现,无序手动开启事务和提交事务,进入方法时自动开启事务,方法执行完全会自动提交事务,如果中途发生了没有处理的异常会自动回滚事务
// 在此方法中使用声明式的事物
// 在进入方法之前,自动开启事务,在方法之前完后,自动提交事务,如果出现异常,则自动回滚事务
@Transactional
@RequestMapping("/add2")
public int add2(UserInfo userInfo) {if(userInfo==null || !StringUtils.hasLength(userInfo.getUsername())|| !StringUtils.hasLength(userInfo.getPassword())) {return 0;}int result = userService.add(userInfo);System.out.println("add2 受影响的行数:" + result);int num = 10/0;return result;
}
去除异常的那行代码重新运行程序
2.3.2 @Transactional 作用域
@Transactional 可以用来修饰方法或类:
- 修饰方法时,只能应用到 public 方法上,否则不生效
- 修饰类时,说明该注解对该类中所有的 public 方法都生效
2.3.3@Transactional 参数设置
参数 | 作用 |
---|---|
value | 当你配置多个事务管理器时,可以使用该属性指定选择用哪个事务管理器 |
transactionManager | 同上 |
propagation | 事务的传播行为,默认值为 Propagation.REQUIRED |
isolation | 事务的隔离级别,默认值为 Isolation.DEFAULT |
timeout | 事务的超时时间,默认值为-1,如果超过该时间限制但事务还没完成,则自动回滚事务 |
readOnly | 指定事务是否为只读事务,默认值为 false,为了忽略那些不需要事务的方法,比如读取数据可以设置 read-only 为 true |
rolibackFor | 用于指定能够触发事务回滚的异常类型,可以指定多个异常类型 |
rolibackForClassName | 同上 |
noRolibackFor | 抛出指定的异常类型,不回滚事务,也可以指定多个异常类型 |
noRollbackForClassName | 同上 |
设置事务的隔离级别
设置事务的超时时间
2.3.4 @Transactional 异常情况
@Transactional 在异常被捕获的情况下,不会进⾏事务⾃动回滚
@Transactional
@RequestMapping("/add3")
public int add3(UserInfo userInfo) {if(userInfo==null || !StringUtils.hasLength(userInfo.getUsername())|| !StringUtils.hasLength(userInfo.getPassword())) {return 0;}int result = userService.add(userInfo);System.out.println("add2 受影响的行数:" + result);try {int num = 10/0;} catch (Exception e) {}return result;
}
解决方法1:将异常重新抛出去
对于捕获的异常,事务是会⾃动回滚的,因此解决⽅案1就是将异常重新抛出
解决方法2:使用代码的方式手动回滚当前事务
手动回滚事务,在⽅法中使⽤ TransactionAspectSupport.currentTransactionStatus() 可以得到当前的事务,然后设置回滚方法 setRollbackOnly 就可以实现回滚了,具体实现代码
@Transactional@RequestMapping("/add3")public int add3(UserInfo userInfo) {if(userInfo==null || !StringUtils.hasLength(userInfo.getUsername())|| !StringUtils.hasLength(userInfo.getPassword())) {return 0;}int result = userService.add(userInfo);System.out.println("add2 受影响的行数:" + result);try {int num = 10/0;} catch (Exception e) {//手动回滚事务TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();}return result;}
2.3.5 @Transactional 工作原理
@Transactional 是基于 AOP 实现的,AOP 又是使用动态代理来实现的。如果目标对象实现了接口,默认情况下采用 JDK 的动态代理,如果目标对象没有实现接口,会使用 CGLIB 动态代理。@Transactional 在开始执行业务之前,通过代理先开启事务,在执行成功之后再提交事务,如果中途遇到异常,则回滚事务
@Transactional 实现思路
@Transactional 具体执行细节
3. 事务隔离级别
3.1 事务特性
事务有四大特性(ACID),原子性、持久性、一致性和隔离性
- 原子性(Atomicity):一个事务中的所有操作,要么全部完成,要么全部不完成。不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚到事务开始前的状态
- 一致性(Consistency):在事务开始之前和事务事务结束之后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精准度、串联性以及后续数据库可以自发性地完成预定的工作
- 持久性(Isolation):事务处理结束后,对数据的修改就是永久的。即使系统故障也不会丢失
- 隔离性(Durability):数据库允许多个并发事务同时对其数据进行读写和修改的能力。隔离性可以防止多个事务并发执行时由交叉执行而导致数据的不一致。
这四个特性中,只有隔离性(隔离级别)是可以设置的
3.2 Spring 中设置事务隔离级别
为什么要设置事务的隔离级别
设置事务的隔离级别是用来保障多个并发事务执行更可控,更符合操作者预期的
这个可控表示的是,比如疫情的时候,有确诊、密接、次密接等针对不同的人群,采取不同的隔离级别,这种方式与事务的隔离级别类似,都是让某种行为操作变的 更可控,事务的隔离级别就是为了防止,其他事务影响当前事务执行的一种策略
MySQL 事务隔离级别有 4 种
- 读未提交(READ UNCOMMITTED ):事务A读到了事务B没有提交的数据,然后过了一会事务B进行了回滚,此时**事务A的这个情况就叫脏读,读到的数据也叫脏数据,读未提交侧重于查询,**既然有了脏读,那么也肯定有不可重复读和幻读的问题
- 读已提交(READ COMMITTED):针对上面脏读的问题来解决的,事务A读到了事务B已经提交的数据,然后过了一会事务B将提交的数据进行修改了,此时事务A又读了一次B的数据,发现两次读到读到数据不一样,这个就叫不可重复读的问题,读已提交侧重的是修改,还是存在不可重复读和幻读的问题
- 可重复读(REPEATABLE READ) :针对的是上面不可重复读的问题,事务A此时查询数据发现表中只有一条数据,然后事务B又过来拆台了,事务B又插入了一条数据,事务A再次查询发现,哎!我出现幻觉了吗,刚刚不是只有一条数据么,现在咋又变成了两条数据了,是出现幻觉了吗,这个问题就叫 幻读,可重复读侧重的是添加和删除,只存在幻读的问题了
- 串行化(SERIALIZABLE):事务最高的隔离级别,解决了脏读、不可重复读、幻读的问题,但这个级别执行效率低
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交(READ UNCOMMITTED) | √ | √ | √ |
读已提交(READ COMMITTED) | √ | √ | |
可重复读(REPEATABLE READ) | √ | ||
串行化(SERIALIZABLE) |
Spring 中事务隔离级别有 5 种
多了一个默认事务隔离级别 DEFAULT 以连接的数据库事务隔离级别为准,如果连接的是 MySQL 那么默认就是 可重复读
注意事项:
- 当 Spring 中设置了事务隔离级别和连接的数据库(MySQL)事务隔离级别发送冲突的时候,以Spring为准
- Spring 中的事务隔离级别机制的实现是依靠连接数据库支持事务隔离级别为基础
Spring 中事务隔离级别可以通过 @Transactional 中的 isolation 属性进行设置
4. Spring 事务传播机制
4.1 事务传播机制是什么
Spring 事务传播机制:多个事务在相互调用时,事务是如何传递的
4.2 为什么需要事务传播机制
事务隔离级别是保证多个并发事务执⾏的可控性的(稳定性的),⽽事务传播机制是保证⼀个事务在多个调⽤⽅法间的可控性的(稳定性的)
4.3 事务传播机制有哪些
事务的传播机制有 7 种:
- Propagation.REQUIRED:默认的事务传播级别,它表示如果当前存在事务,则加入事务;如果当前没有事务,则创建一个新的事务
- Propagation.SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行
- Propagation.MANDATORY;(mandatory 强制性)如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常
- Propagation.REQUIRES_ENW:表示创建一个新的事务,如果当前存在事务,则把当前事务挂起。也就是说不管外部方法是否开启事务,Propagation.REQUIRES_NEW 修饰的内部方法会新开启自己的事务,且开启的事务相互独立,互不干扰
- Propagation.NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起
- Propagation.NEVER:以非事务方式运行,如果当前存在事务,则抛出异常
- Propagation.NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于 PROPAGATION_REQUIRED
4.4 Spring 事务传播机制使用
4.4.1 支持当前事务(REQUIRED 默认)
在mycnblog数据库中,先创建一个表
mysql> create table loginfo(-> id int primary key auto_increment,-> name varchar(250),-> `desc` text,-> createtime datetime default CURRENT_TIMESTAMP);
Query OK, 0 rows affected (0.04 sec)mysql> desc loginfo;
+------------+--------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+-------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(250) | YES | | NULL | |
| desc | text | YES | | NULL | |
| createtime | datetime | YES | | CURRENT_TIMESTAMP | |
+------------+--------------+------+-----+-------------------+----------------+
4 rows in set (0.00 sec)
以下代码实现中,先开启事务先成功插入一条用户数据,然后再执行日志报错,而在日志报错是发生了异常,观察 propagation = Propagation.REQUIRED 的执行结果
@RestController
public class UserController {@Autowiredprivate UserService userService;@Autowiredprivate LogService logService;@Transactional(propagation = Propagation.REQUIRED)@RequestMapping("/add4")public int add4(UserInfo userInfo) {if(userInfo == null || !StringUtils.hasLength(userInfo.getUsername())|| !StringUtils.hasLength(userInfo.getPassword())) {return 0;}int userResult = userService.add(userInfo);System.out.println("添加用户:" + userResult);LogInfo logInfo = new LogInfo();logInfo.setName("添加用户");logInfo.setDesc("添加用户结果:" + userResult);int logResult = logService.add(logInfo);return userResult;}
}
执行结果:程序报错,数据库没有插⼊任何数据
执行流程
-
UserService 中的保存⽅法正常执⾏完成。
-
LogService 保存⽇志程序报错,因为使⽤的是 Controller 中的事务,所以整个事务回滚。
-
数据库中没有插⼊任何数据,也就是步骤 1 中的⽤户插⼊⽅法也回滚了。
4.4.2 不支持当前事务(REQUIRES_NEW)
UserController 类中的代码不变,将添加用户和添加日志的方法修改为 REQUIRES_NEW 不支持当前事务,重新创建事务
运行程序
4.4.3 不支持当前事务(NOT_SUPPORTED)
4.4.4 NESTED 嵌套事务
方法调用流程:Controller/add ——》 用户添加方法(userservice) ——》 日志添加方法(logservice)
当日志添加方法出现异常之后,嵌套事务的执行结果是:
- 用户添加不受影响,添加用户成功
- 日志添加失败,因为发生异常回滚了事务
4.4.5 嵌套事务和加入事务的区别
先看嵌套事务
在 LogService 中进行事务的回滚操作
最终执行的效果就是,User 表成功添加数据,而 Log 表中没有添加数据。Log 中的事务已经回滚,但是嵌套事务不会回滚嵌套之前的事务,也就是说 嵌套事务可以实现部分事务回滚
加入事务
最终程序的执行结果:用户表和日志表都没有添加任何数据,说明整个事务都回滚了。也就是说 REQUIRED 如果回滚就是回滚所有事务,不能实现部分事务的回滚
嵌套事务之所以能够实现部分事务的回滚,是因为事务中有一个保存点(相当于游戏存档),嵌套事务进入之后相当于新建一个保存点,而回滚时只回滚到当前保存点,因此之前的事务是不受影响的。
而 REQUIRED 是加入到当前事务中,并没有创建事务的保存点,因此出现了回滚就是整个事务的回滚
总结二者区别:
- 整个事务如果全部执行成功,二者的结果是一样的
- 如果事务执行到一半失败了,那么加入事务整个事务都会回滚;而嵌套事务会局部回滚,不会影响上一个方法中执行的结果
相关文章:

Spring 事务(编程式事务、声明式事务@Transactional、事务隔离级别、事务传播机制)
文章目录1. 事务的定义2. Spring 中事务的实现2.1 MySQL 中使用事务2.2 Spring 中编程式事务的实现2.3 Spring 中声明式事务2.3.1 声明式事务的实现 Transactional2.3.2 Transactional 作用域2.3.3Transactional 参数设置2.3.4 Transactional 异常情况2.3.5 Transactional 工作…...

车载技术——Window Display之surface的绘制过程与原理
一、Surface 概述 OpenGL ES/Skia定义了一组绘制接口的规范,为什么能够跨平台? 本质上需要与对应平台上的本地窗口建立连接。也就是说OpenGL ES负责输入了绘制的命令,但是需要一个 “画布” 来承载输出结果,最终展示到屏幕。这个…...
2023年全国最新工会考试精选真题及答案10
百分百题库提供工会考试试题、工会考试预测题、工会考试真题、工会证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 51.()是企业工会的权力机关,每年召开一至两次会议。 A.会员大会 B.会…...

pytorch-复现经典深度学习模型-LeNet5
Neural Networks 使用torch.nn包来构建神经网络。nn包依赖autograd包来定义模型并求导。 一个nn.Module包含各个层和一个forward(input)方法,该方法返回output。 一个简单的前馈神经网络,它接受一个输入,然后一层接着一层地传递,…...

【C++】类和对象(上)
文章目录对象的介绍类的介绍类的两种定义方式类的访问限定符及封装访问限定符封装类的作用域类的实例化类的对象模型对象的介绍 C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题; C是基于面向…...

工作中责任链模式用法及其使用场景?
前言 笔者是金融保险行业,有这么一种场景,业务员录完单后提交核保,这时候系统会对保单数据进行校验,如不允许手续费超限校验,客户真实性校验、费率限额校验等等,当校验一多时,维护起来特别麻烦…...

三八女神节有哪些数码好物?2023年三八女神节数码好物清单
2023年的三八女神节就快到了,大家还在烦恼,不知道有哪些数码好物?在此,我来给大家分享几款三八女神节实用性强的数码好物,一起来看看吧。 一、蓝牙耳机:南卡小音舱 参考价:239 推荐理由&…...

FairGuard-Windows加固工具版本更新日志
FairGuard-Windows加固工具1.2.2版本更新日志: ■ 增加Unity Resources资源加密的支持; ■ 增加单独Assetbundle资源加密,并同时支持压缩包和文件夹作为输入的方式; ■ 增加对游戏原文件夹加固的支持; Windows加固方案介绍 FairGuard专为游戏量身定…...

基于RT-Thread完整版搭建的极简Bootloader
项目背景Agile Upgrade: 用于快速构建 bootloader 的中间件。example 文件夹提供 PC 上的示例特性适配 RT-Thread 官方固件打包工具 (图形化工具及命令行工具)使用纯 C 开发,不涉及任何硬件接口,可在任何形式的硬件上直接使用加密、压缩支持如下…...
3.flinkDateStreamAPI介绍env与source
执行环境 Flink可以在不同的环境上下文中运行.可以本地集成开发环境中运行也可以提交到远程集群环境运行. 不同的运行环境对应的flink的运行过程不同,需要首先获取flink的运行环境,才能将具体的job调度到不同的TaskManager 在flink中可以通过StreamExecutionEnvironment类获取…...
$ 2 :数据类型
1.数据类型 1.1基本类型 a、整型int b、浮点型float c、字符型char 1.2构造类型 a、数组[ ] b、结构体struct 1.3指针类型 * 1.4空类型(void) 2.关键字 autoconstdoublefloatintshortstructunsignedbreakcontinueelseforlongsignedswitchvoidcasedefaultenumgotoregistersiz…...

类和对象 - 上
本文已收录至《C语言》专栏! 作者:ARMCSKGT 目录 前言 正文 面向过程与面向对象 面向过程的解决方法 面向对象的解决方法 面向对象的优势 类的引入 早期C类的实现 class定义类 class定义规则 类成员的两种定义方式 类的访问限定符及封装 访…...

补档:红黑树代码实现+简略讲解
红黑树讲解和实现1 红黑树介绍1.1 红黑树特性1.2 红黑树的插入1.3 红黑树的删除2 完整代码实现2.1 rtbtree.h头文件2.2 main.c源文件1 红黑树介绍 红黑树( Red-Black tree,简称RB树)是一种自平衡二叉查找树,是计算机科学中常见的一种数据结构,…...

FirePower X2 14.0.1 for RAD Studio Alexandria
介绍 FirePower X2 FirePower X2 集成了 RAD Studio 11.0 Alexandria 中的新功能,并预览了我们的新特色组件 TwwDataGrouper。 FirePower X2 还允许您为 Apple 的新 M1 芯片构建应用程序,这样您就可以进一步利用 M1 芯片来提高本机应用程序的性能&#x…...
二十九、MongoDB 恢复数据( mongorestore )
MongoDB mongorestore 脚本命令可以用来恢复备份的数据 语法 MongoDB mongorestore 命令脚本语法如下 $ mongorestore -h <hostname><:port> -d dbname <path> 参数说明 -h <:port>, -h<:port> MongoDB 所在服务器地址,默认为 l…...

【数据分析】缺失数据如何处理?pandas
本文目录1. 基础概念1.1. 缺失值分类1.2. 缺失值处理方法2. 缺失观测及其类型2.1. 了解缺失信息2.2. 三种缺失符号2.3. Nullable类型与NA符号2.4. NA的特性2.5. convert_dtypes方法3. 缺失数据的运算与分组 3.1. 加号与乘号规则3.2. groupby方法中的缺失值4. 填充与剔除4.1. fi…...

嵌入式开发--STM32H750VBT6开发中,新版本CubeMX的时钟问题,不能设置到最高速度480MHZ
嵌入式开发–STM32H750VBT6开发中,新版本CubeMX的时钟问题,不能设置到最高速度480MHZ 问题描述 之前开发的项目,开发环境是CubeMX6.6.1,H7系列的支持包版本是1.10.0。跑得没问题,最近需要对项目做修改,同…...

一文读懂PaddleSpeech中英混合语音识别技术
语音识别技术能够让计算机理解人类的语音,从而支持多种语音交互的场景,如手机应用、人车协同、机器人对话、语音转写等。然而,在这些场景中,语音识别的输入并不总是单一的语言,有时会出现多语言混合的情况。例如&#…...

问题三十四:傅立叶变换——高通滤波
高通滤波器是一种可以通过去除图像低频信息来增强高频信息的滤波器。在图像处理中,高通滤波器常常用于去除模糊或平滑效果,以及增强边缘或细节。在本篇回答中,我们将使用Python和OpenCV实现高通滤波器。 Step 1:加载图像并进行傅…...
flink 键控状态(keyed state)
github开源项目flink-note的笔记。本博客的实现代码都写在项目的flink-state/src/main/java/state/keyed/KeyedStateDemo.java文件中。 项目github地址: github 1. flink键控状态 flink键控状态是作用与flink KeyedStream上的,也就是说需要将DataStream先进行keyby之后才能使…...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...