Spring5学习笔记—Spring事务处理

news2024/11/26 23:29:23

Springgif.gif

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉
🍎个人主页:Leo的博客
💞当前专栏: Spring专栏
✨特色专栏: MySQL学习
🥭本文内容:Spring5学习笔记—Spring事务处理
🖥️个人小站 :个人博客,欢迎大家访问
📚个人知识库: 知识库,欢迎大家访问

1. 什么是事务

事务是逻辑上的一组操作,要么都执行,要么都不执行。

相信大家应该都能背上面这句话了,下面我结合我们日常的真实开发来谈一谈。

我们系统的每个业务方法可能包括了多个原子性的数据库操作,比如下面的 save() 方法中就有两个原子性的数据库操作。这些原子性的数据库操作是有依赖的,它们要么都执行,要不就都不执行。

	public void save() {
		personDao.save(student);
		personDetailDao.save(studentDetail);
	}

另外,需要格外注意的是:事务能否生效数据库引擎是否支持事务是关键。比如常用的 MySQL 数据库默认使用支持事务的 innodb引擎。但是,如果把数据库引擎变为 myisam,那么程序也就不再支持事务了

事务是保证业务操作完整性的一种数据库机制。

事务的4特点: A C I D
1. A(Atomicity) 	原子性 
2. C(Consistency) 	一致性
3. I(Isolation)		隔离性
4. D(durability) 	持久性
  1. 原子性Atomicity):事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
  2. 一致性Consistency):执行事务前后,数据保持一致,例如转账业务中,无论事务是否成功,转账者和收款人的总额应该是不变的;
  3. 隔离性Isolation):并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
  4. 持久性Durability):一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

🌈:只有保证了事务的持久性、原子性、隔离性之后,一致性才能得到保障。也就是说 A、I、D 是手段,C 是目的!

image-20230828202040602

2. Spring对事务的支持

Spring支持的两种事务管理

3.1 编程式事务管理

通过 TransactionTemplate或者TransactionManager手动管理事务,实际应用中很少使用。

使用TransactionTemplate 进行编程式事务管理的示例代码如下:

@Autowired
private TransactionTemplate transactionTemplate;
public void testTransaction() {

        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                try {

                    // ....  业务代码
                } catch (Exception e){
                    //回滚
                    transactionStatus.setRollbackOnly();
                }

            }
        });
}

使用 TransactionManager 进行编程式事务管理的示例代码如下:

@Autowired
private PlatformTransactionManager transactionManager;

public void testTransaction() {

  TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
          try {
               // ....  业务代码
              transactionManager.commit(status);
          } catch (Exception e) {
              transactionManager.rollback(status);
          }
}

3.2 声明式事务管理

这一种方式实际上比较推荐的,实际是通过 AOP 实现(基于@Transactional 的全注解方式使用最多)。

使用 @Transactional注解进行事务管理的示例代码如下:

public class Test {

    @Transactional(propagation = Propagation.REQUIRED)
    public void method() {
        /** 做业务**/
        MethodOne mb = new MethodOne();
        MethodOne mc = new MethodOne();
        mb.bMethod();
        mc.cMethod();
    }
}

Spring主要通过以下三个接口对事务进行管理

  • PlatformTransactionManager:(平台)事务管理器,Spring 事务策略的核心。
  • TransactionDefinition:事务定义信息(事务隔离级别、传播行为、超时、只读、回滚规则)。
  • TransactionStatus:事务运行状态。

我们可以把 PlatformTransactionManager 接口可以被看作是事务上层的管理者,而 TransactionDefinitionTransactionStatus 这两个接口可以看作是事务的描述。

PlatformTransactionManager 会根据 TransactionDefinition 的定义比如事务超时时间、隔离级别、传播行为等来进行事务管理 ,而 TransactionStatus 接口则提供了一些方法来获取事务相应的状态比如是否新事务、是否可以回滚等等。

1. PlatformTransactionManager

简称事务管理接口

image-20230828200844565

PlatformTransactionManager接口中定义了三个方法:

package org.springframework.transaction;

import org.springframework.lang.Nullable;

public interface PlatformTransactionManager {
    //获得事务
    TransactionStatus getTransaction(@Nullable TransactionDefinition var1) throws TransactionException;
    //提交事务
    void commit(TransactionStatus var1) throws TransactionException;
    //回滚事务
    void rollback(TransactionStatus var1) throws TransactionException;
}
2. TransactionDefinition

简称事务属性

事务管理器接口 PlatformTransactionManager 通过 getTransaction(TransactionDefinition definition) 方法来得到一个事务,这个方法里面的参数是 TransactionDefinition 类 ,这个类就定义了一些基本的事务属性。

什么是事务属性呢? 事务属性可以理解成事务的一些基本配置,描述了事务策略如何应用到方法上。

事务属性包含了 5 个方面:

  • 隔离级别
  • 传播行为
  • 回滚规则
  • 是否只读
  • 事务超时

TransactionDefinition 接口中定义了 5 个方法以及一些表示事务属性的常量比如隔离级别、传播行为等等。

package org.springframework.transaction;

import org.springframework.lang.Nullable;

public interface TransactionDefinition {
    int PROPAGATION_REQUIRED = 0;
    int PROPAGATION_SUPPORTS = 1;
    int PROPAGATION_MANDATORY = 2;
    int PROPAGATION_REQUIRES_NEW = 3;
    int PROPAGATION_NOT_SUPPORTED = 4;
    int PROPAGATION_NEVER = 5;
    int PROPAGATION_NESTED = 6;
    int ISOLATION_DEFAULT = -1;
    int ISOLATION_READ_UNCOMMITTED = 1;
    int ISOLATION_READ_COMMITTED = 2;
    int ISOLATION_REPEATABLE_READ = 4;
    int ISOLATION_SERIALIZABLE = 8;
    int TIMEOUT_DEFAULT = -1;
    // 返回事务的传播行为,默认值为 REQUIRED。
    int getPropagationBehavior();
    //返回事务的隔离级别,默认值是 DEFAULT
    int getIsolationLevel();
    // 返回事务的超时时间,默认值为-1。如果超过该时间限制但事务还没有完成,则自动回滚事务。
    int getTimeout();
    // 返回是否为只读事务,默认值为 false
    boolean isReadOnly();

    @Nullable
    String getName();
}
3. TransactionStatus

简称事务状态

TransactionStatus接口用来记录事务的状态 该接口定义了一组方法,用来获取或判断事务的相应状态信息。

PlatformTransactionManager.getTransaction(…)方法返回一个 TransactionStatus 对象。

TransactionStatus 接口内容如下:

public interface TransactionStatus{
    boolean isNewTransaction(); // 是否是新的事务
    boolean hasSavepoint(); // 是否有恢复点
    void setRollbackOnly();  // 设置为只回滚
    boolean isRollbackOnly(); // 是否为只回滚
    boolean isCompleted; // 是否已完成
}

Spring对事务的支持

⚠️ 再提醒一次:你的程序是否支持事务首先取决于数据库 ,比如使用 MySQL 的话,如果你选择的是 innodb 引擎,那么恭喜你,是可以支持事务的。但是,如果你的 MySQL 数据库使用的是 myisam 引擎的话,那不好意思,从根上就是不支持事务的。

MySQL 怎么保证原子性的?

我们知道如果想要保证事务的原子性,就需要在异常发生时,对已经执行的操作进行回滚,在 MySQL 中,恢复机制是通过 回滚日志(undo log) 实现的,所有事务进行的修改都会先记录到这个回滚日志中,然后再执行相关的操作。如果执行过程中遇到异常的话,我们直接利用 回滚日志 中的信息将数据回滚到修改之前的样子即可!并且,回滚日志会先于数据持久化到磁盘上。这样就保证了即使遇到数据库突然宕机等情况,当用户再次启动数据库的时候,数据库还能够通过查询回滚日志来回滚之前未完成的事务。

Spring对事务控制

JDBC:
Connection.setAutoCommit(false);
Connection.commit();
Connection.rollback();
Mybatis:
Mybatis自动开启事务

​ sqlSession(Connection).commit();
​ sqlSession(Connection).rollback();

结论:控制事务的底层 都是Connection对象完成的。

3. Spring控制事务的开发步骤:

Spring是通过AOP的方式进行事务的开发、

3.1 目标对象

public class XXXUserServiceImpl{
   private xxxDAO xxxDAO
   set get

   1. 原始对象 ---》 原始方法 ---》核心功能 (业务处理+DAO调用)
   2. DAO作为Service的成员变量,依赖注入的方式进行赋值
}

3.2 额外功能

1. org.springframework.jdbc.datasource.DataSourceTransactionManager
2. 注入DataSource 
1. MethodInterceptor
   public Object invoke(MethodInvocation invocation){
   	  //原理:
      try{
        Connection.setAutoCommit(false);
        Object ret = invocation.proceed();
        Connection.commit();
      }catch(Exception e){
        Connection.rollback();
      }
        return ret;
   }
2. @Aspect
   @Around 

3.3 切入点

@Transactional
事务的额外功能加入给哪些业务方法。

  1. 类上:类中所有的方法都会加入事务
  2. 方法上:这个方法会加入事务

3.4 组装切面

1. 切入点
2. 额外功能

<tx:annotation-driven transaction-manager=""/>

4. Spring控制事务的真实编码:

  • 搭建开发环境:

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>5.1.14.RELEASE</version>
    </dependency>
    
  • 编码:

    <!-- 原始对象 -->
    <bean id="userService" class="com.baizhiedu.service.UserServiceImpl">
    	<property name="userDAO" ref="userDAO"/>
    </bean>
    
    <!--DataSourceTransactionManager-->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 需要Connection 而Connection又在dataSource里 -->
     	<property name="dataSource" ref="dataSource"/>
    </bean>
    
    @Transactional
    public class UserServiceImpl implements UserService {
        private UserDAO userDAO;
    <!-- 告诉Spring开启基于注解的事务管理 -->
    <tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
    
  • 细节:

    <tx:annotation-driven transaction-manager="dataSourceTransactionManager" proxy-target-class="true"/>
    进行动态代理底层实现的切换   proxy-target-class
    	默认	false JDK
    		 true  Cglib 
    

5. Spring的事务属性

事务属性简称 Transaction Attribute

5.1 什么是事务属性?

属性:描述物体特征的一系列值
性别 身高 体重 …
事务属性:描述事务特征的一系列值

  1. 隔离属性
  2. 传播属性
  3. 只读属性
  4. 超时属性
  5. 异常属性

5.2 如何添加事务属性

@Transactional(isloation=,propagation=,readOnly=,timeout=,rollbackFor=,noRollbackFor=,)

5.3 事务属性详解

1. 隔离属性 (ISOLATION)

  • 隔离属性的概念

    概念:他描述了事务解决并发问题的特征
    1. 什么是并发
           多个事务(用户)在同一时间,访问操作了相同的数据
           
           同一时间:0.000几秒 微小前 微小后
    2. 并发会产生那些问题
           1. 脏读
           2. 不可重复读
           3. 幻影读
    3. 并发问题如何解决
           通过隔离属性解决,隔离属性中设置不同的值,解决并发处理过程中的问题。
    
  • 事务并发会产生的问题

    • 脏读

      一个事务,读取了另一个事务中没有提交的数据。会在本事务中产生数据不一致的问题
      解决方案 @Transactional(isolation=Isolation.READ_COMMITTED)

  • 不可重复读

    一个事务中,多次读取相同的数据,但是读取结果不一样。会在本事务中产生数据不一致的问题
    注意:1 不是脏读 2 一个事务中
    解决方案 @Transactional(isolation=Isolation.REPEATABLE_READ)
    本质: 一把行锁

    • 幻影读

      一个事务中,多次对整表进行查询统计,但是结果不一样,会在本事务中产生数据不一致的问题
      解决方案 @Transactional(isolation=Isolation.SERIALIZABLE)
      本质:表锁

    • 总结

      并发安全: SERIALIZABLE > REPEATABLE_READ > READ_COMMITTED
      运行效率: READ_COMMITTED > REPEATABLE_READ > SERIALIZABLE

  • 数据库对于隔离属性的支持

    隔离属性值MySQLOracle
    ISOLATION_READ_COMMITTED
    IOSLATION_REPEATABLE_READ
    ISOLATION_SERIALIZABLE

    Oracle不支持REPEATABLE_READ值 如何解决不可重复读?
    采用的是多版本比对的方式 解决不可重复读的问题

  • 默认隔离属性

    ISOLATION_DEFAULT:会调用不同数据库所设置的默认隔离属性

    MySQL : REPEATABLE_READ
    Oracle: READ_COMMITTED

  • 查看数据库默认隔离属性

    • MySQL

        select @@tx_isolation;
      
    • Oracle

      SELECT s.sid, s.serial#,
           CASE BITAND(t.flag, POWER(2, 28))
              WHEN 0 THEN 'READ COMMITTED'
              ELSE 'SERIALIZABLE'
           END AS isolation_level
        FROM v$transaction t 
        JOIN v$session s ON t.addr = s.taddr
        AND s.sid = sys_context('USERENV', 'SID');
      
  • 隔离属性在实战中的建议

    推荐使用Spring指定的ISOLATION_DEFAULT

    1. MySQL repeatable_read
    2. Oracle read_commited

    未来实战中,并发访问情况,很少

    如果真遇到并发问题,乐观锁
    Hibernate(JPA) Version
    MyBatis 通过拦截器自定义开发

2. 传播属性(PROPAGATION)

  • 传播属性的概念:

    概念:他描述了事务解决嵌套问题的特征

    什么叫做事务的嵌套:他指的是一个大的事务中,包含了若干个小的事务

    问题:大事务中融入了很多小的事务,他们彼此影响,最终就会导致外部大的事务,丧失了事务的原子性

image-20230828155139656

  • 传播属性的值极其用法:

    传播属性的值外部不存在事务外部存在事务用法备注
    REQUIRED开启新的事务融合到外部事务中@Transactional(propagation = Propagation.REQUIRED)增删改方法
    SUPPORTS不开启事务融合到外部事务中@Transactional(propagation = Propagation.SUPPORTS)查询方法
    REQUIRES_NEW开启新的事务挂起外部事务,创建新的事务@Transactional(propagation = Propagation.REQUIRES_NEW)日志记录方法中
    NOT_SUPPORTED不开启事务挂起外部事务@Transactional(propagation = Propagation.NOT_SUPPORTED)及其不常用
    NEVER不开启事务抛出异常@Transactional(propagation = Propagation.NEVER)及其不常用
    MANDATORY抛出异常融合到外部事务中@Transactional(propagation = Propagation.MANDATORY)及其不常用
  • 默认传播属性:

    Propagation.REQUIRED

  • 推荐传播属性的使用方式

    增删改 方法:直接使用默认值REQUIRED
    查询 操作:显示指定传播属性的值为SUPPORTS

3. 只读属性(readOnly)

针对于只进行查询操作的业务方法,可以加入只读属性,提供运行效率

默认值:false

4. 超时属性(timeout)

指定了事务等待的最长时间

  1. 为什么事务进行等待?
    当前事务访问数据时,有可能访问的数据被别的事务进行加锁的处理,那么此时本事务就必须进行等待。
  2. 等待时间 秒
  3. 如何应用 @Transactional(timeout=2)
  4. 超时属性的默认值 -1
    最终由对应的数据库来指定

5. 异常属性

Spring事务处理过程中
默认 对于RuntimeException及其子类 采用的是回滚的策略
默认 对于Exception及其子类 采用的是提交的策略

rollbackFor = {java.lang.Exception,xxx,xxx}
noRollbackFor = {java.lang.RuntimeException,xxx,xx}

@Transactional(rollbackFor = {java.lang.Exception.class},noRollbackFor = {java.lang.RuntimeException.class})

建议:实战中使用RuntimeExceptin及其子类 使用事务异常属性的默认值

5.4 事务属性常见配置总结

  1. 隔离属性 默认值
  2. 传播属性 Required(默认值) 增删改 Supports 查询操作
  3. 只读属性 readOnly false 增删改 true 查询操作
  4. 超时属性 默认值 -1
  5. 异常属性 默认值

增删改操作 @Transactional
查询操作 @Transactional(propagation=Propagation.SUPPORTS,readOnly=true)

5.5 基于标签的事务配置方式(事务开发的第二种形式)

  • 基于注解 @Transaction的事务配置回顾

    <bean id="userService" class="com.baizhiedu.service.UserServiceImpl">
      <property name="userDAO" ref="userDAO"/>
    </bean>
    
    <!--DataSourceTransactionManager-->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      <property name="dataSource" ref="dataSource"/>
    </bean>
    
    @Transactional(isolation=,propagation=,...)
    public class UserServiceImpl implements UserService {
        private UserDAO userDAO;
    
    <tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
    
  • 基于标签的事务配置:

    <bean id="userService" class="com.baizhiedu.service.UserServiceImpl">
      <property name="userDAO" ref="userDAO"/>
    </bean>
    
    <!--DataSourceTransactionManager-->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      <property name="dataSource" ref="dataSource"/>
    </bean>
    
    <!-- 事务属性 -->
    <tx:advice id="txAdvice" transacation-manager="dataSourceTransactionManager">
        <tx:attributes>
              <tx:method name="register" isoloation="",propagation=""></tx:method>
              <tx:method name="login" .....></tx:method>
              等效于 
              @Transactional(isolation=,propagation=,)
              public void register(){
            
              }
          
        </tx:attributes>
    </tx:advice>
    
    <aop:config>
         <aop:pointcut id="pc" expression="execution(* com.baizhiedu.service.UserServiceImpl.register(..))"></aop:pointcut>
         <aop:advisor advice-ref="txAdvice" pointcut-ref="pc"></aop:advisor>
    </aop:config>
    
  • 基于标签的事务配置在实战中的应用方式

    <bean id="userService" class="com.baizhiedu.service.UserServiceImpl">
      <property name="userDAO" ref="userDAO"/>
    </bean>
    
    <!--DataSourceTransactionManager-->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      <property name="dataSource" ref="dataSource"/>
    </bean>
    
    编程时候 service中负责进行增删改操作的方法 都以modify开头
                           查询操作 命名无所谓 
    <tx:advice id="txAdvice" transacation-manager="dataSourceTransactionManager">
        <tx:attributes>
              <tx:method name="register"></tx:method>
              <tx:method name="modify*"></tx:method>
              <tx:method name="*" propagation="SUPPORTS"  read-only="true"></tx:method>
        </tx:attributes>
    </tx:advice>
    
    应用的过程中,service放置到service包中
    <aop:config>
         <aop:pointcut id="pc" expression="execution(* com.baizhiedu.service..*.*(..))"></aop:pointcut>
         <aop:advisor advice-ref="txAdvice" pointcut-ref="pc"></aop:advisor>
    </aop:config>
                  查询操作 命名无所谓 
    <tx:advice id="txAdvice" transacation-manager="dataSourceTransactionManager">
        <tx:attributes>
              <tx:method name="register"></tx:method>
              <tx:method name="modify*"></tx:method>
              <tx:method name="*" propagation="SUPPORTS"  read-only="true"></tx:method>
        </tx:attributes>
    </tx:advice>
    
    应用的过程中,service放置到service包中
    <aop:config>
         <aop:pointcut id="pc" expression="execution(* com.baizhiedu.service..*.*(..))"></aop:pointcut>
         <aop:advisor advice-ref="txAdvice" pointcut-ref="pc"></aop:advisor>
    </aop:config>
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/940770.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

day 6 c++

#include <iostream>using namespace std; class Animal { public:Animal(){cout << "训练员的无参构造" << endl;}virtual void perform(){} }; class Tiger:public Animal {string tezheng;string biaoyan; public:Tiger(){cout << "…

【C++】C++ 引用详解 ⑨ ( 常量引用初始化 | C / C++ 常量分配内存的四种情况 )

文章目录 一、常量引用初始化1、使用 " 普通变量 " 初始化 " 常量引用 "2、使用 " 常量 / 字面量 " 初始化 " 常量引用 "3、C / C 常量分配内存的四种情况4、代码示例 - 常量引用初始化 一、常量引用初始化 1、使用 " 普通变量 &…

Apache SeaTunnel 2.3.3 版本发布,CDC 支持 Schema Evolution!

时隔两个月&#xff0c; Apache SeaTunnel 终于迎来大版本更新。此次发布的 2.3.3 版本在功能和性能上均有较大优化改进&#xff0c;其中大家期待已久的 CDC Schema evolution&#xff08;DDL 变更同步&#xff09;、主键 Split 拆分、JDBC Sink 自动建表功能、SeaTunnel Zeta …

C语言每日一题 ---- 打印从1到最大的n位数(Day 1)

本专栏为c语言练习专栏&#xff0c;适合刚刚学完c语言的初学者。本专栏每天会不定时更新&#xff0c;通过每天练习&#xff0c;进一步对c语言的重难点知识进行更深入的学习。 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;C语言天天练 &#x…

基于Java+SpringBoot+Vue前后端分离疾病防控综合系统设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

Linux系统编程系列之进程间通信(IPC)-信号

一、什么是信号 信号是进程间通信的一种方式&#xff0c;它是异步通信的。而异步的意思就是不同步&#xff0c;事件的发生和处理没有协同。 二、信号的特性 Linux/Unix系统下&#xff0c;信号总共分成两大类&#xff0c;一类是最常用的标准信号&#xff0c;另一类是后面的引入…

Python怎么解决性能问题?

Python的性能问题可以通过以下一些方法来解决或改善&#xff1a; 使用更高效的算法和数据结构&#xff1a; 选择适当的数据结构和算法可以显著提升代码的性能。了解不同算法的时间复杂度和空间复杂度&#xff0c;选择最适合问题的解决方案。 优化代码逻辑&#xff1a; 仔细审查…

yolov8使用C++推理的流程及注意事项

1.下载yolov8项目源码GitHub - ultralytics/ultralytics: NEW - YOLOv8 &#x1f680; in PyTorch > ONNX > OpenVINO > CoreML > TFLite 2.下载opencvReleases - OpenCV,建议版本>4.7.0,选择下载源码&#xff0c; windows版本由于使用的编译器与我们所使用的m…

5年测试,面试结束后被HR发朋友圈怼了..(心塞)

前一阵子向朋友诉苦&#xff0c;我在参加字节跳动面试的时候被面试官怼得哑口无言&#xff0c;场面让我一度十分尴尬。 印象最深的就是下面几个问题&#xff1a; 根据你以前的工作经验和学习到的测试技术&#xff0c;说说你对质量保证的理解&#xff1f; 非关系型数据库和关系型…

关于MySQL数据页的一些认识

1. 一个数据页有很多个槽&#xff0c;每个槽对应一个分组&#xff0c;槽指向分组的最大数据行记录&#xff0c;查找时通过二分法定位数据所在组 从数据页的角度看 B 树 | 小林coding 【Mysql】InnoDB 引擎中的页目录 - 知乎 2. 每个行记录是通过单链表来存储的 3. 数据页之…

教会你怎么使用SpringMVC 文件上传

&#x1f600;前言 教会你怎么使用SpringMVC 文件上传 &#x1f3e0;个人主页&#xff1a;尘觉主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是尘觉&#xff0c;希望我的文章可以帮助到大家&#xff0c;您的满意是我的动力&#x1f609;&#x1f609; 在csdn获…

java入坑之网络编程

一、 网络基础知识 1.1网卡 1.2IP地址 1.3端口 1.4保留IP 1.5网络协议 二、UDP 编程 2.1相关概念 计算机通讯&#xff1a;数据从一个IP的port出发&#xff08;发送方&#xff09;&#xff0c;运输到另外一个IP的port&#xff08;接收方&#xff09; UDP&#xff1a;无连接无…

EXSI技术--Exsi简介与安装

1.EXSI简介 了解可直接安装到您的物理服务器的、可靠的裸机 Hypervisor。通过直接访问并控制底层资源,VMware ESXi可有效地对硬件进行分区,以便整合应用并降低成本。它是业界领先的高效体系架构,在可靠性、性能和支持方面树立了行业标杆。(裸金属架构) VMware vSphere的虚拟…

CSDN每日一练 |『影分身』『小鱼的航程(改进版)』『排查网络故障』2023-08-25

CSDN每日一练 |『影分身』『小鱼的航程&#xff08;改进版&#xff09;』『排查网络故障』2023-08-25 一、题目名称&#xff1a;影分身二、题目名称&#xff1a;小鱼的航程(改进版)三、题目名称&#xff1a;排查网络故障 一、题目名称&#xff1a;影分身 时间限制&#xff1a;1…

【java并发编程的艺术读书笔记】ConcurrentHashMap是如何保证线程安全的

ConcurrentHashMap HashMap的线程安全问题 并发环境下HashMap可能会导致程序死循环&#xff0c;原因是put操作可能会使得HashMap中的链表结构成环&#xff0c;导致无法找到next节点&#xff0c;无限循环 HashTable为什么效率低 HashMap是使用synchronized来保证县城安全的&…

计算机网络MTU和MSS的区别

在计算机网络中&#xff0c;MTU代表最大传输单元&#xff08;Maximum Transmission Unit&#xff09;&#xff0c;而MSS代表最大分节大小&#xff08;Maximum Segment Size&#xff09;。 1.MTU&#xff08;最大传输单元&#xff09;&#xff1a; MTU是指在网络通信中&#x…

C语言初阶测评题:测试你的基础知识和编程技能!!

&#x1f493;博客主页&#xff1a;江池俊的博客⏩收录专栏&#xff1a;C语言刷题专栏&#x1f449;专栏推荐&#xff1a;✅C语言初阶之路 ✅C语言进阶之路&#x1f4bb;代码仓库&#xff1a;江池俊的代码仓库&#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐ 文…

【C语言】探讨蕴藏在表达式求解中的因素

&#x1f6a9;纸上得来终觉浅&#xff0c; 绝知此事要躬行。 &#x1f31f;主页&#xff1a;June-Frost &#x1f680;专栏&#xff1a;C语言 &#x1f525;该篇将探讨 操作符 和 类型转换 对表达式求解的影响。 目录&#xff1a; 隐式类型转换算术转换操作符的属性❤️ 结语 隐…

调用自实现MyGetProcAddress获得CreateFileA函数并调用创建写入文件

写文件如下 #include <iostream> #include <Windows.h>typedef HANDLE(WINAPI* CreateFileAFunc)(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);DWORD MyGetProcAddress(_In_ HMODULE hModule,_In_ LPCSTR lpProcName ){PIMAGE_DOS_HEADE…

南京邮电大学《基于编译原理的表达式计算器》

文章目录 一、课题内容和要求二、课题需求分析1 过程分析2 设计分析 三、课题相关数据结构及算法设计1 主要数据结构2 主要算法流程3 词法分析4 语法分析5 中间代码生成6 LR语法分析程序6.1识别活前缀的DFA6.2 SLR(1)分析表6.3 分析过程 四、源程序代码1 源代码层次结构2.1 ana…