【JavaEE进阶】Spring事务和事务传播机制

news2024/11/19 5:35:46

文章目录

  • 一. 什么是Spring事务
  • 二. Spring中事务的实现
    • 1. Spring编程式事务
    • 2. 声明式事务
      • 2.1 trycatch下事务不会自动回滚的解决方案
      • 2.2 @Transactional 作用范围
      • 2.3 @Transactional 参数说明
      • 2.4 @Transactional 工作原理
  • 三. 事务的隔离级别
    • 1. 事务的四大特性
    • 2. Spring中设置事务隔离级别
  • 四. Spring事务传播机制
    • 1. 事务传播机制
    • 2. 为什么需要事务传播机制
    • 3. 事务传播机制有哪些

一. 什么是Spring事务

Spring 事务是 Spring 框架提供的一种机制,用于管理数据库操作或其他资源的一组相关操作,以确保它们在一个原子、一致、可靠和隔离的执行单元内进行。事务用于维护数据的完整性并支持并发访问数据库时的数据一致性。

Spring 事务的主要特点包括:

  1. 原子性(Atomicity):事务中的所有操作要么全部成功执行,要么全部不执行。如果事务中的任何一个操作失败,则整个事务将被回滚到初始状态,以保持数据的一致性。
  2. 一致性(Consistency):事务在执行之前和之后都必须使数据库保持一致状态。这意味着事务中的操作会遵循预定义的业务规则,以确保数据的有效性和完整性。
  3. 隔离性(Isolation):事务的隔离级别定义了事务之间的相互影响程度。Spring 支持多个隔离级别,例如读未提交、读已提交、可重复读和串行化。通过设置适当的隔离级别,可以控制事务之间的并发读写操作带来的数据不一致问题。
  4. 可靠性(Durability):事务在成功提交后,对数据的更新将永久保存到数据库中,即使系统发生故障或重启,数据也不会丢失。

Spring 事务通过 AOP(面向切面编程)实现,Spring事务操作分为了两种方式:

  1. 编程式事务(⼿动写代码操作事务)。
  2. 声明式事务(利⽤注解⾃动开启和提交事务)。

使用 Spring 事务可以将多个数据库操作或其他资源访问操作组织成一个逻辑单元,并确保这些操作要么全部成功执行,要么全部回滚。这有助于提高应用程序的可靠性、一致性和并发性。

其实在之前的MySQL部分,我们对事务已经有了初步的了解,忘记的小伙伴可以查看: MySQL:索引事务

二. Spring中事务的实现

1. Spring编程式事务

Spring编程式事务是是一种通过编写代码显式管理事务的方法,而不依赖于注解或配置文件。它提供了更细粒度的事务控制,允许在方法级别或代码块级别指定事务的起始、提交和回滚。
Spring手动操作事务和MySQL 操作事务类似,主要有三个操作步骤:

  1. 开启事务
  2. 提交事务
  3. 回滚事务

SpringBoot内置了两个对象,DataSourceTransactionManager用来获取事务(开启事务)、提交或回滚事务的,而TransactionDefinition是事务的属性,在获取事务的时候需要将
TransactionDefinition传递进去从而获得一个事务TransactionStatus,实现代码如下:

package com.example.demo.controller;

import com.example.demo.service.UserService;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

//编程式事务:
@RestController
@RequestMapping("/user")
public class UserController {
    @Resource
    private UserService userService;
    //Jdbc事务管理器
    @Resource
    private DataSourceTransactionManager transactionManager;
    //定义事务属性
    @Resource
    private TransactionDefinition transactionDefinition;

    @RequestMapping("/del")
    public int del(Integer id){
        if(id == null || id < 0){
            return 0;
        }
        //1. 开启事务
        TransactionStatus transactionStatus = null;
        int result = 0;
        try{
            transactionStatus = transactionManager.getTransaction((transactionDefinition));
            //业务操作,删除用户
            result = userService.del(id);
            System.out.println("删除: "+result);
            //2. 提交事务/回滚事务
            transactionManager.commit(transactionStatus);//提交事务

        }catch (Exception e){
            if(transactionStatus != null){
                transactionManager.rollback(transactionStatus);//回滚事务
            }
        }
        return result;
    }

}

在这里插入图片描述
启动程序,然后在浏览器中输入:即为删除id为1的admin
在这里插入图片描述
在这里插入图片描述
可以看到管理员成功被删除.
若要实现回滚操作:

@RequestMapping("/del")
    public int del(Integer id){
        if(id == null || id < 0){
            return 0;
        }
        //1. 开启事务
        TransactionStatus transactionStatus = null;
        int result = 0;
            transactionStatus = transactionManager.getTransaction((transactionDefinition));
            //业务操作,删除用户
            result = userService.del(id);
            System.out.println("删除: "+result);
            //2. 提交事务/回滚事务
//            transactionManager.commit(transactionStatus);//提交事务
            transactionManager.rollback(transactionStatus);//回滚事务
        return result;
    }


我们可以看到,虽然编程式事务可以实现事务,但是操作很繁琐,接下来,我们可以使用较为简单的声明式事务.

2. 声明式事务

声明式事务是利用注解自动开启和提交事务.
声明式事务的实现很简单,只需在方法上加入@Transactional 注解就可以实现,无需手动开启事务和提交事务,进入方法时自动开启事务,方法执行完会自动提交事务,如果途中发生了没有处理的异常就会自动回滚事务.

package com.example.demo.controller;

import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user2")
public class UserController2 {
    @Autowired
    private UserService userService;

    @Transactional(timeout = 3) // 在方法开始之前开启事务,方法正常执行结束之后提交事务,如果执行途中发生异常,则回滚事务
    @RequestMapping("/del")
    public int del(Integer id) {
        if (id == null || id <= 0) return 0;
        return userService.del(id);
    }
}

运行成功:
在这里插入图片描述
如果代码中有异常的话:

    @Transactional(timeout = 3) // 在方法开始之前开启事务,方法正常执行结束之后提交事务,如果执行途中发生异常,则回滚事务
    @RequestMapping("/del")
    public int del(Integer id) {
        if (id == null || id <= 0) return 0;
        int num = 10/0;
        return userService.del(id);
    }

在这里插入图片描述

2.1 trycatch下事务不会自动回滚的解决方案

但是如果加上Try catch来处理异常,此时事务就不会回滚了,数据也就正式被删除了.但是出现这种情况,它就是出现了异常,我们是想要它进行回滚操作的.我们有两种处理办法:
1. 手动抛出异常

 @Transactional(timeout = 3) // 在方法开始之前开启事务,方法正常执行结束之后提交事务,如果执行途中发生异常,则回滚事务
    @RequestMapping("/del")
    public int del(Integer id) {
        if (id == null || id <= 0) return 0;
        int result = 0;
        try{
            result = userService.del(id);
            System.out.println(result);
            int num = 10/0;
        }catch (Exception e){
            throw e;//手动将异常抛出
        }
        return result;
    }

2. 手动回滚事务

    @Transactional(timeout = 3) // 在方法开始之前开启事务,方法正常执行结束之后提交事务,如果执行途中发生异常,则回滚事务
    @RequestMapping("/del")
    public int del(Integer id) {
        if (id == null || id <= 0) return 0;
        int result = 0;
        try{
            result = userService.del(id);
            System.out.println(result);
            int num = 10/0;
        }catch (Exception e){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return result;
    }

TransactionAspectSupport.currentTransactionStatus()用于获取到当前事务,setRollbackOnly()是用于回滚的方法.

2.2 @Transactional 作用范围

@Transactional 可以用来修饰方法或类:

  1. 修饰方法时:需要注意只能应用到 public方法上,否则不生效。推荐此种用法。
  2. 修饰类时:表明该注解对该类中所有的public方法都生效。

2.3 @Transactional 参数说明

参数作用
value当配置了多个事务管理器时,可以使用该属性指定选择哪个事务管理器.
transactionManager当配置了多个事务管理器时,可以使用该属性指定选择哪个事务管理器.
propagation事务的传播行为,默认值为Propagation.REQUIRED
isolation事务的隔离级别,默认值为lsolation.DEFAULT
timeout事务的超时时间,默认值为-1.如果超过该时间限制但事务还没有完成,则自动回滚事务.
readOnly指定事务是否为只读事务,默认值为false;为了忽略那些不需要事务的方法,比如读取数据,可以设置read-only为true.
rollbackFor用于指定能够触发事务回滚的异常类型,可以指定多个异常类型.
rollbackForClassName用于指定能够触发事务回滚的异常类型,可以指定多个异常类型.
noRollbackFor抛出指定的异常类型,不回滚事务,也可以指定多个异常类型.
noRollbackForClassName抛出指定的异常类型,不回滚事务,也可以指定多个异常类型.

2.4 @Transactional 工作原理

@Transactional 的工作原理如下:

  1. 在方法执行前,Spring 根据 @Transactional 注解的配置来创建一个事务上下文,并将其与当前线程关联起来。
  2. 当方法开始执行时,Spring 检查当前线程是否已经关联了一个事务上下文。如果没有关联,则根据 @Transactional 注解的配置,启动一个新的事务。
  3. 方法执行过程中,如果没有发生异常,则 Spring 会在方法执行结束后提交事务,将对数据库的更改持久化到数据库。
  4. 如果方法执行过程中抛出了异常,Spring 将捕获该异常并判断是否需要回滚事务。根据 @Transactional 注解的配置,如果异常属于回滚规则中指定的类型,则发起事务回滚操作,撤销已经执行的数据库操作。
  5. 最后,Spring 根据事务的提交或回滚结果,进行相应的清理工作,关闭事务上下文。

需要注意的是:@Transactional 注解只对公共方法生效,因此仅能应用于公共的非静态方法.

除了直接将 @Transactional 注解应用于方法上,还可以将其应用于类上。在这种情况下,所有在该类中声明的方法都将具有相同的事务属性。

@Transactional 注解通过简化事务管理过程,提供了一种声明式的事务管理方式,使开发者能够更轻松地实现对数据库操作的事务性控制。

总之,@Transactional是基于AOP实现的,AOP又是使用动态代理实现的。如果目标对象实现了接口,默认情况下会采用JDK的动态代理,如果目标对象没有实现了接口,会使用CGLIB动态代理。@Transactional在开始执行业务之前,通过代理先开启事务,在执行成功之后再提交事务。如果中途遇到的异常,则回滚事务。
在这里插入图片描述
在这里插入图片描述

三. 事务的隔离级别

1. 事务的四大特性

事务的四大特性(ACID)是指原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability),它们是关系型数据库管理系统(RDBMS)中用于保证数据操作的可靠性和一致性的基本属性。

  1. 原子性(Atomicity):事务是一个原子操作单元,要么全部执行成功,要么全部失败回滚。它是不可分割的最小操作单位,将多个操作视为一个整体进行处理。如果事务中的任何一项操作失败,所有已经执行的操作将被撤销,数据库回到事务开始前的状态。
  2. 一致性(Consistency):事务的执行使数据库从一个一致状态转移到另一个一致状态。在事务开始之前和事务结束之后,数据库的完整性约束没有被破坏。这意味着事务在执行过程中不能破坏数据库的完整性、一致性约束以及业务规则。
  3. 隔离性(Isolation):多个并发事务之间应该相互隔离,每个事务的执行都应该与其他事务隔离开来,互不干扰。事务隔离级别定义了多个事务同时运行时各自可见的数据以及彼此之间的互动程度。常见的隔离级别有读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)和串行化(Serializable)。
  4. 持久性(Durability):事务一旦提交,它对数据库中的数据变更就是永久性的,即使发生系统崩溃或电源故障等意外情况,数据库也能够保证已提交的事务不会丢失。持久性是通过将事务日志记录到磁盘或其他持久化介质来实现的。

这四个特性确保了事务的安全性、可靠性和一致性。它们是关系型数据库管理系统保证数据操作的基本要求,同时也是在设计应用程序时需要考虑和遵循的事务规范。
这四种特性中,只有隔离性(隔离级别)是可以设置的。

2. Spring中设置事务隔离级别

之前在MySQL中我们学过的事务隔离级别有四种.忘记的小伙伴可以查看:MySQL:索引事务.
此处我们要讲解的是Spring中的事务隔离级别,在 Spring 中,可以通过 @Transactional 注解的isolation属性来设置事务的隔离级别。isolation 属性接受一个枚举值,用于指定所需的隔离级别。

Spring中的事务隔离级别分为五种,分别是:

  1. DEFAULT:使用底层数据库的默认隔离级别。
  2. READ_UNCOMMITTED:读取未提交的数据。最低的隔离级别,在此级别下,一个事务可以读取到其他事务尚未提交的数据。
  3. READ_COMMITTED:读取已提交的数据。该级别下,一个事务只能读取到其他事务已经提交的数据,避免了脏读。
  4. REPEATABLE_READ:可重复读。在此级别下,事务开始时读取的数据集合将被固定,即使其他事务修改了数据,当前事务仍然看到最初读取的数据集合。防止了脏读和不可重复读。
  5. SERIALIZABLE:串行化。在此级别下,事务是按顺序一个接一个地执行,避免了脏读、不可重复读和幻读。

具体实现格式如下:

@Transactional(isolation = Isolation.READ_COMMITTED)
public void doSomething() {
    // 事务操作
}

四. Spring事务传播机制

1. 事务传播机制

事务传播机制是指在多个事务操作嵌套执行时,各事务之间如何相互关联和影响的规则。

2. 为什么需要事务传播机制

事务传播机制的存在是为了**处理多个事务操作之间的关系和影响,以确保数据的一致性和完整性。**以下是一些需要事务传播机制的情况:

  1. 嵌套调用:当一个事务方法内部调用另一个事务方法时,事务传播机制可以控制这两个事务之间的关系。通过适当的传播行为配置,可以使内部方法加入当前事务、创建新的事务或以非事务方式执行,从而确保多个事务操作在正确的事务上下文中执行。
  2. 业务流程:在一个业务流程中可能涉及多个事务操作,比如订单处理过程中的库存扣减、支付确认和物流更新等。事务传播机制可以确保这些事务操作在合适的事务边界内进行,避免数据不一致的情况发生。
  3. 多线程并发:在多线程环境下,不同的线程可能同时执行事务操作。事务传播机制可以在并发执行的情况下维护事务的隔离性和原子性,避免数据冲突和并发问题。
  4. 异常处理:在事务中,如果出现异常,事务传播机制可以决定是继续传播异常还是回滚事务。通过配置合适的传播行为,可以在异常发生时采取适当的处理方式,以保证数据的一致性。

总之,事务传播机制允许我们在多个事务操作中控制事务的行为方式,确保数据的正确处理和一致性。通过合理配置事务传播行为,可以满足不同的应用场景下对事务处理的需求。
在这里插入图片描述
在这里插入图片描述

3. 事务传播机制有哪些

Spring框架提供了七种事务传播行为,用于控制事务方法的执行方式:
(包含例子:假设你正在计划一次旅行。你需要预订机票、酒店和租车,并确保这些操作在旅行期间的可用性和连贯性。)

  1. REQUIRED(默认):如果当前已经存在事务,则加入该事务中执行;如果当前没有事务,则创建一个新的事务。这是最常用的传播行为。

    当你预订机票时,系统首先检查目标航班的余票情况,然后从你的账户中扣除相应金额作为机票费用。如果你的预订操作已经在一个事务中,那么检查余票和扣款将加入到该事务中。如果没有事务,则创建一个新的事务来执行这两个操作。

  2. SUPPORTS:如果当前已经存在事务,则加入该事务中执行;如果当前没有事务,则以非事务方式执行。适合于不需要强制事务的场景。

    当你查询酒店房间的可用性时,系统根据你选择的日期和地点返回相关信息。如果你的 查询操作已经在一个事务中,那么查询房间可用性将加入到该事务中。如果没有事务,则以非事务方式执行查询。

  3. MANDATORY:如果当前已经存在事务,则加入该事务中执行;如果当前没有事务,则抛出异常。适合于必须依赖事务的场景。

    当你要修改预订的租车时间时,系统需要验证该租车订单是否存在。在租车订单修改方法中,通过判断当前是否存在事务来决定是否允许修改操作。如果你已经在事务中,则允许修改;如果没有事务,则抛出异常。

  4. REQUIRES_NEW:无论当前是否存在事务,都会挂起当前事务,创建一个新的事务执行。适合于需要独立的事务执行的场景。(事务挂起是指在执行一个事务的过程中,暂时中断该事务的执行,并将其保存在一个临时状态下,以便执行其他事务。当挂起的事务恢复执行时,会从挂起的点继续执行。)

    当你取消酒店预订时,需要先将预订状态设为取消,并返还预付款项。无论你当前是否处于一个事务中,这两个操作都将在一个新的事务中执行,并将原来的事务挂起。

  5. NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,则将其挂起。适合于不需要事务支持的场景。

    当你查询机票价格时,系统根据出发地和目的地返回相关信息。如果你当前处于一个事务中,该查询操作将以非事务方式执行,而不会干扰原有事务的状态。

  6. NEVER:以非事务方式执行操作,如果当前存在事务,则抛出异常。适合于不能在事务中执行的场景。

    当你申请旅行保险时,需要确保该操作不会在任何事务中执行。如果你当前处于一个事务中,则抛出异常并禁止执行保险申请操作,以确保操作的独立性。

  7. NESTED:如果当前已经存在事务,则在嵌套事务中执行;如果当前没有事务,则创建一个新的事务。嵌套事务有自己的保存点,并可以回滚到保存点。适合于需要嵌套事务支持的场景。

    当你进行机票改签操作时,需要先将原机票设为无效,然后生成一张新的机票。如果你当前已经在一个事务中,那么这两个操作将在嵌套事务中执行,嵌套事务有自己的保存点,并可以回滚到保存点。如果没有事务,则创建一个新的事务来执行这两个操作。

例如:

@Transactional(propagation = Propagation.REQUIRED)
public void methodA() {
    // 事务操作
    methodB();
}

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void methodB() {
    // 事务操作
}

在上面的例子中,methodA()使用了默认的传播行为REQUIRED,如果当前存在事务,则methodB()将加入该事务;而methodB()使用了传播行为REQUIRES_NEW,无论当前是否存在事务,都将创建一个新的事务来执行。

通过选择合适的事务传播行为并进行配置,可以确保在多个事务操作中正确地管理事务的行为和关系,从而维护数据的一致性和完整性。

在这里插入图片描述
嵌套事务和加入事务的区别:
嵌套事务和加入事务都是事务传播机制的不同实现方式,它们之间有以下区别:

  1. 事务范围:
  • 嵌套事务是内部事务运行在外部事务的范围内,可以看作是外部事务的子事务,嵌套事务可以独立提交或回滚。
  • 加入事务是将一个方法或代码片段加入到已有的事务中,与外部事务共享同一个事务范围,不能单独提交或回滚。
  1. 事务行为:
  • 嵌套事务具有独立的事务保存点,可以在内部事务中进行回滚操作,而不会影响外部事务的状态。内部事务执行成功后,可以选择提交到外部事务或者继续嵌套使用。
  • 加入事务没有独立的事务保存点,它的所有操作都与外部事务绑定,只有外部事务提交时,才会将加入事务的操作一同提交。
  1. 使用场景:
  • 嵌套事务适用于需要在一个事务中执行多个独立的子操作,并且子操作可以单独回滚的情况。如果需要某个子操作的失败不会影响其他子操作,可以使用嵌套事务。
  • 加入事务适用于需要将一段代码或方法加入到已有事务中执行的情况,例如在一个服务方法中调用其他服务方法,希望它们共享同一个事务。通过加入事务,可以确保这些方法在一个事务中执行,并且要么都成功提交,要么都回滚。

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

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

相关文章

15 mysql tiny/meidum/long blob/text 的数据存储

前言 这里主要是 由于之前的一个 datetime 存储的时间 导致的问题的衍生出来的探究 探究的主要内容为 int 类类型的存储, 浮点类类型的存储, char 类类型的存储, blob 类类型的存储, enum/json/set/bit 类类型的存储 本文主要 的相关内容是 tiny/medium/long blob/text 类…

基于电气特征分析(ESA)的状态监测是如何实现的?

在现代工业和生产环境中&#xff0c;设备的正常运行和高效性对于维持生产的连续性和质量至关重要。然而&#xff0c;设备的故障和损坏可能会导致生产中断、不必要的维修成本以及生产效率的下降。为了应对这些挑战&#xff0c;状态监测技术已成为工业界的重要工具之一&#xff0…

C++之std::search应用实例(一百八十九)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

Redis数据结构总结

Redis 是一款开源的&#xff0c;内存中的数据结构存储系统&#xff0c;它可以用作数据库、缓存和消息代理。Redis 支持多种类型的数据结构&#xff0c;如字符串&#xff08;String&#xff09;、哈希&#xff08;Hashes&#xff09;、列表&#xff08;Lists&#xff09;、集合&…

45、springboot 文件上传到指定磁盘路径 及 上传成功后的文件回显

需求&#xff1a; 写一个文件上传的功能&#xff0c;把文件上传到指定的文件夹。 然后上传成功后的文件回显 ★ Spring Boot对文件上传提供的自动配置支持 Spring Boot的文件上传自动配置主要由 MultipartAutoConfiguration 和 MultipartProperties 两个类组成。MultipartPro…

linux并发服务器 —— 多线程并发(六)

线程概述 同一个程序中的所有线程均会独立执行相同程序&#xff0c;且共享同一份全局内存区域&#xff1b; 进程是CPU分配资源的最小单位&#xff0c;线程是操作系统调度执行的最小单位&#xff1b; Linux环境下&#xff0c;线程的本质就是进程&#xff1b; ps -Lf pid&…

【方案】基于视频与AI智能分析技术的城市轨道交通视频监控建设方案

一、背景分析 地铁作为重要的公共场所交通枢纽&#xff0c;流动性非常高、人员大量聚集&#xff0c;轨道交通需要利用视频监控系统来实现全程、全方位的安全防范&#xff0c;这也是保证地铁行车组织和安全的重要手段。调度员和车站值班员通过系统监管列车运行、客流情况、变电…

MySQL数据库——多表查询(3)-自连接、联合查询、子查询

目录 自连接 查询语法 自连接演示 联合查询 查询语法 子查询 介绍 标量子查询 列子查询 行子查询 表子查询 自连接 通过前面的学习&#xff0c;我们对于连接已经有了一定的理解。而自连接&#xff0c;通俗地去理解就是自己连接自己&#xff0c;即一张表查询多次。…

Python小知识 - 一致性哈希算法

一致性哈希算法 一致性哈希算法&#xff08;Consistent Hashing Algorithm&#xff09;是用于解决分布式系统中节点增减比较频繁的问题。它的思想是&#xff0c;将数据映射到0~2^64-1的哈希空间中&#xff0c;并通过哈希函数对数据进行映射&#xff0c;计算出数据所在的节点。当…

【LeetCode75】第四十三题 钥匙和房间

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 给我们一个数组&#xff0c;表示对应的房间里拥有能开启的对应索引号的钥匙。 一开始我们只能进入0号房间&#xff0c;也就是数组里索引…

图像OCR转文字,验证码识别技术太疯狂-UI软件自动化

现在用PYTHON识别图片文字&#xff0c;PaddleOCR&#xff0c;Tesseract,Opencv等很多开源技术。知识大爆炸年代&#xff0c;几年不学习就跟不上时代了。 以前早的时候一个验证码图片上有4个不同颜色字符&#xff0c;带一些杂点&#xff0c;我写点代码按颜色最多的进行提取&…

Angular安全专辑之三 —— 授权绕过,利用漏洞控制管理员账户

这篇文章是针对实际项目中所出现的问题所做的一个总结。简单来说&#xff0c;就是授权绕过问题&#xff0c;管理员帐户被错误的接管。 详细情况是这样的&#xff0c;我们的项目中通常都会有用户身份验证功能&#xff0c;不同的用户拥有不同的权限。相对来说管理员账户所对应的…

Al智能问答工具HelpLook招募推荐官啦!

我们在使用AI智能问答软件的时候&#xff0c;可以多去留意一下软件的一些推广活动&#xff0c;比如说像是HelpLook这个软件&#xff0c;他有专门设置推广返利计划&#xff0c;在拉动更多新用户的同时做到回馈老用户。今天looklook就来讲一下&#xff0c;具体这个计划是怎么样的…

11 mysql float/double/decimal 的数据存储

前言 这里主要是 由于之前的一个 datetime 存储的时间 导致的问题的衍生出来的探究 探究的主要内容为 int 类类型的存储, 浮点类类型的存储, char 类类型的存储, blob 类类型的存储, enum/json/set/bit 类类型的存储 本文主要 的相关内容是 float, decimal 类类型的相关数据…

如何在 Vue TypeScript 项目使用 emits 事件

Vue是构建出色的Web应用程序的最灵活、灵活和强大的JavaScript框架之一。Vue中最重要的概念和关键特性之一是能够促进应用程序组件之间的通信。让我们深入探讨一下Vue中的“emits”概念&#xff0c;并了解它们如何以流畅和无缝的方式实现父子组件之间的通信。 Vue中的emits是什…

layui 新增tab标签页

// $("#fjyj").click(function () {// //window.location.href "/sysconfig/SuperVisorEdit";// navigateToTeamPersonModule(/CollectData/GradeWarning/EduIndex, 分级预警);// });function navigateToTeamPersonModule(url, name) {var ids n…

前几天写的博客被选中进入【CSDN月度精选】榜单

小收获&#xff0c;记录一下&#xff0c;哈哈 这个貌似是CSDN给的排名和得分&#xff1a;

AI人员打闹监测识别算法

AI人员打闹监测识别算法通过yolopython网络模型框架算法&#xff0c; AI人员打闹监测识别算法能够准确判断出是否有人员进行打闹行为&#xff0c;算法会立即发出预警信号。Yolo算法&#xff0c;其全称是You Only Look Once: Unified, Real-Time Object Detection&#xff0c;其…

ArcGIS美化科研论文地图(利用在线底图)

1.加载在线底图服务 在ArcGIS Desktop中打开Catalog窗口&#xff0c;在GIS Servers中点击Add ArcGIS Server&#xff0c;之后选项全部默认&#xff0c;仅在URL中输入以下网址https://services.arcgisonline.com/arcgis 之后就可以看到底图了 我们在WorldElevation3D中选择Nat…