Spring高手之路25——深入解析事务管理的切面本质

简介: 本篇文章将带你深入解析Spring事务管理的切面本质,通过AOP手动实现 @Transactional 基本功能,并探讨PlatformTransactionManager的设计和事务拦截器TransactionInterceptor的工作原理,结合时序图详细展示事务管理流程,最后引导分析 @Transactional 的代理机制源码,帮助你全面掌握Spring事务管理。

1. 事务管理的切面本质

  事务管理在Spring中的实现依赖于AOP,而AOP主要通过代理机制来实现。具体而言,AOP通过代理对象拦截对目标方法的调用,并在方法调用前后插入事务管理逻辑。拦截器机制是AOP实现的一部分,用于定义具体的增强逻辑。

  Spring能够通过AOP将事务管理逻辑独立出来,作为一个切面应用于所有标注了 @Transactional 的方法。代理对象会拦截对这些方法的调用,并在方法执行前后插入事务管理逻辑。

  在事务管理中,拦截器机制起到了关键作用。Spring使用 TransactionInterceptor 拦截器来处理事务逻辑。TransactionInterceptor 在方法调用之前开启事务,在方法执行过程中进行事务管理,并在方法调用结束后根据执行结果提交或回滚事务。这种机制确保了事务管理逻辑与业务逻辑的解耦,提高了代码的可维护性和可读性。

2. 用AOP手动实现 @Transactional 基本功能

  为了能更清晰的理解到@Transactional本质就是AOP,我们自行实现一个@MyTransactional 注解,来简单模拟@Transactional的功能。

  我这里为了演示API的使用,在代码演示的时候会设置事务的隔离级别为READ_COMMITTED,设置事务的传播行为为REQUIRES_NEW

全部代码如下:

  1. 数据库表创建

首先,创建 test 表:

CREATE TABLE `test` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4
  1. 配置数据源、MyBatis和事务管理器
package com.example.demo.configuration;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;

@Configuration
@ComponentScan(basePackages = "com.example.demo")
@MapperScan("com.example.demo.mapper")
@EnableAspectJAutoProxy
public class AppConfig {
   
    @Bean
    public DataSource dataSource() {
   
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/demo");
        dataSource.setUsername("root");
        dataSource.setPassword("password");
        return dataSource;
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
   
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mybatis/**/*.xml"));
        return sqlSessionFactoryBean.getObject();
    }

    @Bean
    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
   
        return new SqlSessionTemplate(sqlSessionFactory);
    }
    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
   
        return new DataSourceTransactionManager(dataSource);
    }
}
  1. 创建 Mapper 接口和 XML 映射文件

这里TestMapper.javaTestMapper.xml定义了数据库操作方法。

TestMapper.java:

package com.example.demo.mapper;

import com.example.demo.model.Test;


public interface TestMapper {
   
    // 定义插入Test的方法
    void insertTest(Test test);

    // 定义根据ID查询Test的方法
    Test selectTestById(Long id);
}

TestMapper.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.TestMapper">

    <!-- 插入记录到test表 -->
    <insert id="insertTest" parameterType="com.example.demo.model.Test">
        INSERT INTO test (name) VALUES (#{name})
    </insert>

    <!-- 根据ID查询test表中的记录 -->
    <select id="selectTestById" parameterType="long" resultType="com.example.demo.model.Test">
        SELECT * FROM test WHERE id = #{id}
    </select>

</mapper>
  1. 创建模型类

Test.java定义了数据表对应的实体类。

Test.java:

package com.example.demo.model;

// 定义Test类与数据库表test对应
public class Test {
   
    private Long id; // 主键ID
    private String name; // 名称

    // 获取ID
    public Long getId() {
   
        return id;
    }

    // 设置ID
    public void setId(Long id) {
   
        this.id = id;
    }

    // 获取名称
    public String getName() {
   
        return name;
    }

    // 设置名称
    public void setName(String name) {
   
        this.name = name;
    }
}
  1. 创建自定义事务注解

MyTransactional.java:

package com.example.demo.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

// 自定义事务注解
@Target({
   ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTransactional {
   
}
  1. 创建事务管理切面

TransactionAspect.java:

package com.example.demo.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

@Aspect // 声明这是一个切面类
@Component // 将这个类标记为 Spring 组件
public class TransactionAspect {
   

    @Autowired // 注入事务管理器
    private PlatformTransactionManager transactionManager;

    // 环绕通知,拦截所有标注了 @MyTransactional 的方法
    @Around("@annotation(com.example.demo.annotation.MyTransactional)")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
   
        // 创建默认事务定义
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        // 设置事务的传播行为为REQUIRES_NEW
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
        // 设置事务的隔离级别为READ_COMMITTED
        def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        // 获取事务状态对象,开启事务
        TransactionStatus status = transactionManager.getTransaction(def);
        Object result;
        try {
   
            result = pjp.proceed(); // 执行目标方法
            transactionManager.commit(status); // 提交事务
        } catch (Throwable ex) {
   
            transactionManager.rollback(status); // 回滚事务
            throw ex;
        }
        return result; // 返回结果
    }
}
  1. 创建 Service

TestService.java:

package com.example.demo.service;

import com.example.demo.mapper.TestMapper;
import com.example.demo.model.Test;
import com.example.demo.annotation.MyTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service // 标记这个类为 Spring 服务组件
public class TestService {
   

    @Autowired // 注入 TestMapper
    private TestMapper testMapper;

    // 使用自定义的 @MyTransactional 注解
    @MyTransactional
    public void createTest(Test test) {
   
        testMapper.insertTest(test); // 插入记录

        // 模拟异常以测试事务回滚
        if ("error".equals(test.getName())) {
   
            throw new RuntimeException("Simulated error");
        }
    }

    // 根据 ID 查询记录
    public Test getTestById(Long id) {
   
        return testMapper.selectTestById(id);
    }
}
  1. Main 方法

创建一个 Main 方法来启动 Spring 应用程序并执行测试逻辑:

MainApp.java:

package com.example.demo;

import com.example.demo.configuration.AppConfig;
import com.example.demo.model.Test;
import com.example.demo.service.TestService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class DemoApplication {
   
    public static void main(String[] args) {
   
        // 加载 Spring 配置文件
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

        // 获取 TestService Bean
        TestService testService = context.getBean(TestService.class);

        try {
   
            Test test = new Test();
            test.setName("success");
            testService.createTest(test);
            System.out.println("Test with name 'success' created.");
        } catch (Exception e) {
   
            System.out.println("Failed to create test with name 'success': " + e.getMessage());
        }

        try {
   
            Test test = new Test();
            test.setName("error");
            testService.createTest(test);
        } catch (Exception e) {
   
            System.out.println("Failed to create test with name 'error': " + e.getMessage());
        }
    }
}

执行结果如下:

在这里插入图片描述

在这里插入图片描述

  注意:使用 DefaultTransactionDefinition 来设置事务的隔离级别和传播行为时,这些设置是针对当前事务的,而不是针对整个数据库会话的。具体来说,事务的隔离级别和传播行为是在事务管理器(例如 DataSourceTransactionManager)控制的事务范围内有效。

  当设置事务的隔离级别为 READ_COMMITTED 时,实际上是针对当前事务的连接设置的。这意味着在当前事务的生命周期内(从事务开始到提交或回滚),该隔离级别是有效的。一旦事务结束,连接的隔离级别会被重置为默认值。

  在 JDBCSpring 框架中,事务的隔离级别通常用整数来表示。以下是这些隔离级别及其对应的整数值:

  • TransactionDefinition.ISOLATION_DEFAULT (0): 默认隔离级别,这个值依赖于底层数据库的默认设置。
  • TransactionDefinition.ISOLATION_READ_UNCOMMITTED (1): 读未提交。这是最低的隔离级别,允许读取未提交的数据,可能会导致脏读。
  • TransactionDefinition.ISOLATION_READ_COMMITTED (2): 读已提交。只允许读取已提交的数据,可以防止脏读。
  • TransactionDefinition.ISOLATION_REPEATABLE_READ (4): 可重复读。保证在同一个事务中多次读取相同数据的结果是一致的,防止不可重复读。
  • TransactionDefinition.ISOLATION_SERIALIZABLE (8): 串行化。这是最高的隔离级别,确保事务完全串行化执行,防止脏读、不可重复读和幻读,但性能较低。

3. PlatformTransactionManager的设计

  从上面可以看到,提交事务和回滚事务都是由PlatformTransactionManager对象操作的。PlatformTransactionManager是做什么的?

  在日常开发中,虽然我们通常使用@Transactional注解来管理事务,但实际上PlatformTransactionManager在后台起着关键作用。Spring的事务管理是通过代理机制和AOP(面向切面编程)来实现的,PlatformTransactionManager就是在这个过程中被使用的核心组件。

PlatformTransactionManager接口定义了以下主要方法:

1. getTransaction(TransactionDefinition definition):

  • 这是用于开始一个新的事务或返回当前事务的句柄的方法。它根据传入的TransactionDefinition(事务定义)参数来决定是否需要开启一个新事务,或者参与一个现有的事务。比如,若是REQUIRES_NEW,代表如果没有事务存在,它会创建一个新的事务。
  • TransactionDefinition参数包括事务的传播行为、隔离级别、超时时间和是否只读等属性。

  句柄(handle)在编程中的作用可以理解为一种引用或者标识符,也可以理解为指针。用来间接地访问某个资源或对象。句柄的目的是简化和抽象资源管理,不需要直接操作底层资源,只需要通过句柄来进行操作。
  Spring事务管理中,句柄用来表示事务的状态和上下文。这个句柄并不是实际的事务对象,而是对事务的一种引用或标识,使得Spring框架可以管理事务的生命周期。
现实生活中的类比
图书馆借书卡:

  • 在图书馆中,你有一张借书卡,这张借书卡上有一个唯一的编号。
  • 借书卡相当于一个句柄,它并不直接代表你借的书,而是代表在图书馆的借书权限和记录。
  • 当你想借书或还书时,只需要出示这张借书卡,图书馆的系统会通过借书卡的编号找到你的借书记录,完成借书或还书操作。

在编程中,句柄扮演的角色类似于借书卡的编号,通过句柄可以间接地操作或访问实际的资源。

2. commit(TransactionStatus status):

  • 提交给定的事务,TransactionStatus包含了事务的具体信息。
  • 如果事务被成功提交,则对数据库的所有更改将被保存。

3. rollback(TransactionStatus status):

  • 回滚给定的事务,TransactionStatus包含了事务的具体信息。
  • 如果事务被回滚,则对数据库的所有更改将被撤销。

4. 事务拦截器TransactionInterceptor

  在Spring中,事务拦截器是通过AOP(面向切面编程)机制实现的。事务拦截器会拦截标注了@Transactional注解的方法调用,并在方法执行前后管理事务。

  1. 事务管理的启用

  在Spring应用中,事务管理通常通过@EnableTransactionManagement注解启用,这会注册必要的基础设施来处理事务。

@Configuration
@EnableTransactionManagement
public class AppConfig {
   
    // 配置数据源和事务管理器
}
  1. 事务拦截器的配置

  @EnableTransactionManagement会配置一个事务顾问(advisor)和一个事务拦截器(interceptor)。这些组件在Spring容器启动时被注册。

关键类和接口

  1. TransactionManagementConfigurationSelector:负责选择启用事务管理所需的配置类。
  2. ProxyTransactionManagementConfiguration:具体配置类,负责注册事务管理相关的bean
  3. TransactionInterceptor:事务拦截器,实际负责事务管理的逻辑。

TransactionInterceptor的工作原理

  TransactionInterceptorSpring事务管理的核心组件之一,它实现了MethodInterceptor接口,通过AOP拦截标注了@Transactional的方法,并在方法执行前后进行事务管理。

TransactionInterceptor的源码位置

  TransactionInterceptor类位于org.springframework.transaction.interceptor包中。以下是其关键部分的简化代码和解释

package org.springframework.transaction.interceptor;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor {
   

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
   
        // 获取目标方法
        Method method = invocation.getMethod();
        // 获取事务属性
        TransactionAttributeSource tas = getTransactionAttributeSource();
        TransactionAttribute txAttr = tas.getTransactionAttribute(method, invocation.getThis().getClass());

        // 获取事务管理器
        PlatformTransactionManager tm = determineTransactionManager(txAttr);

        // 如果没有事务属性或事务管理器,则直接执行方法
        if (txAttr == null || tm == null) {
   
            return invocation.proceed();
        }

        // 创建事务模板
        TransactionTemplate tt = createTransactionTemplate(tm, txAttr);
        // 开启事务,执行目标方法,并管理事务提交或回滚
        return tt.execute(new TransactionCallback<Object>() {
   
            @Override
            public Object doInTransaction(TransactionStatus status) {
   
                try {
   
                    return invocation.proceed();
                } catch (Throwable ex) {
   
                    // 回滚事务
                    status.setRollbackOnly();
                    throw new RuntimeException(ex);
                }
            }
        });
    }
}

时序图如下:

在这里插入图片描述
过程描述

  1. 客户端调用目标方法:
  • 客户端发起对目标方法的调用。
  • 这一调用被 TransactionInterceptor 拦截。
  1. 获取事务属性:
  • TransactionInterceptor 通过 TransactionAttributeSource 获取目标方法的事务属性。
  • 事务属性包括事务的传播行为、隔离级别、超时设置等。
  • TransactionAttributeSource 返回获取到的事务属性。
  1. 确定事务管理器:
  • TransactionInterceptor 确定要使用的 PlatformTransactionManager
  1. 获取事务管理器:
  • 根据事务属性获取适当的事务管理器。
  • 事务管理器负责管理事务的生命周期(开始、提交、回滚)。
  1. 检查事务属性和事务管理器:
  • TransactionInterceptor 检查是否获取到事务属性和事务管理器。
  • 如果没有获取到事务属性或事务管理器,则直接执行目标方法,不进行事务管理。
  • TransactionInterceptor 调用目标方法并返回执行结果。
  1. 创建事务模板:
  • 如果获取到事务属性和事务管理器,TransactionInterceptor 创建一个 TransactionTemplate
  • TransactionTemplate 用于简化事务操作。
  1. 使用事务模板执行目标方法:
  • TransactionInterceptor 使用 TransactionTemplate 开启事务并执行目标方法。
  1. 方法执行成功:
  • 如果目标方法执行成功,事务模板提交事务。
  • 事务模板返回执行结果。
  • TransactionInterceptor 将结果返回给客户端。
  1. 方法执行抛出异常:
  • 如果目标方法抛出异常,事务模板回滚事务。
  • 事务模板抛出异常。
  • TransactionInterceptor 将异常抛出给客户端。

  Spring启动时,@EnableTransactionManagement启用事务管理,Spring会自动配置事务拦截器TransactionInterceptor。当调用标注了@Transactional的方法时,TransactionInterceptor会拦截该方法,并通过PlatformTransactionManager管理事务的开启、提交和回滚。

总结

  • @EnableTransactionManagement启用事务管理,并注册必要的事务管理组件。
  • TransactionInterceptor通过AOP拦截事务方法,并管理事务的开启、提交和回滚。
  • PlatformTransactionManager在后台执行实际的事务操作。

有兴趣的小伙伴可以自行去学习了解TransactionInterceptor 如何处理事务,以及在事务属性解析、事务管理器选择等方面的具体实现。

5. 时序图展示事务管理流程

这里展示处理事务时的作用流程,包含多种事务传播行为的判断。

在这里插入图片描述

详细步骤解释

1. 调用带有@Transactional的方法:

  • 客户端调用标注了@Transactional的方法。
  • AOP拦截器拦截该方法调用。

2. 获取事务:

  • AOP拦截器,也就是事务拦截器,调用PlatformTransactionManagergetTransaction(TransactionDefinition)方法获取事务。
  • 事务管理器检查当前事务上下文,确定是否需要创建新事务或加入现有事务。

3. 处理传播行为:

  • 根据TransactionDefinition中的传播行为(Propagation Behavior)决定事务的处理方式。
  • REQUIRED:如果没有现有事务,创建新事务;如果已有事务,加入现有事务。
  • REQUIRES_NEW:总是创建新事务,如果已有事务,则挂起当前事务。
  • SUPPORTS:如果有现有事务,则加入现有事务;如果没有事务,则以非事务方式执行。
  • NOT_SUPPORTED:如果有现有事务,则挂起当前事务,以非事务方式执行。
  • MANDATORY:如果没有现有事务,则抛出异常。
  • NEVER:如果有现有事务,则抛出异常。
  • NESTED:如果有现有事务,则创建嵌套事务;如果没有事务,则创建新事务。

4. 执行目标方法:

  • AOP拦截器通知客户端继续执行业务逻辑。
  • 客户端执行数据库操作(例如保存实体)。

5. 提交或回滚事务:

如果业务逻辑执行过程中抛出异常:

  • AOP拦截器调用事务管理器的rollback(TransactionStatus)方法。
  • 事务管理器执行回滚操作,并返回回滚状态。
  • AOP拦截器将异常抛回给客户端。

如果业务逻辑正常执行完毕:

  • AOP拦截器调用事务管理器的commit(TransactionStatus)方法。
  • 事务管理器执行提交操作,并返回提交状态。
  • AOP拦截器将结果返回给客户端。

6. 事务与线程的关系——@Transactional方法内的异步线程

  在写业务的时候可以会遇到,一个方法内部有数据库操作和异步线程的操作,如果是数据库操作的异常,这肯定会回滚,如果数据库操作正常,异步线程执行的时候出现异常,数据库操作会回滚吗?

用一个例子简洁的说明

@Service
public class OrderService {
   

    @Autowired
    private OrderRepository orderRepository;

    @Transactional
    public void placeOrder(Order order) {
   
        // 保存订单
        orderRepository.save(order);

        // 启动异步任务
        CompletableFuture.runAsync(() -> {
   
            try {
   
                // 模拟异步任务抛出异常
                if (true) {
   
                    throw new RuntimeException("异步任务出错");
                }
            } catch (Exception e) {
   
                // 异常处理逻辑
                // 记录日志,发送告警等
                System.err.println("异步任务异常: " + e.getMessage());
            }
        });

        // 其他业务逻辑
    }
}

答案如下:

  在@Transactional方法中直接启动的异步线程如果抛出异常,不会导致整个事务回滚。事务的边界仅限于当前线程,异步线程中的异常不会影响主事务。

事务和线程的关系如下

  1. 事务绑定到线程上下文
  • Spring的事务管理是基于TransactionSynchronizationManager来管理事务状态的。
  • 每个事务在当前线程中开始,事务状态(如是否提交或回滚)存储在当前线程的ThreadLocal变量中。这意味着事务的边界是线程级的。
  1. @Transactional的工作原理
  • 当一个方法被@Transactional注解修饰时,Spring会通过AOP创建一个代理,该代理会在方法调用之前开启事务,在方法完成之后根据方法执行情况提交或回滚事务。
  • 事务的开始和结束都发生在当前线程中,即事务的边界局限于执行该方法的线程。

异步线程与事务的独立性

  1. 异步任务在不同的线程中执行:
  • 异步任务通常使用@Async注解、CompletableFuture.runAsyncnew Thread或自定义线程池来启动。无论哪种方式,异步任务会在一个新的线程中运行。
  • 新线程没有继承原始线程的ThreadLocal变量,包括事务上下文,因此异步线程不参与主事务。
  1. 事务状态的隔离:
  • 主线程中执行的事务与异步线程中的操作是独立的。即使异步线程中抛出异常,也不会影响主线程的事务状态。
  • 异步线程中的异常只会在异步线程中传播,不会传播回主线程。

总结

  • Spring的事务管理是线程绑定的,每个事务与启动它的线程绑定。
  • 异步任务在不同的线程中执行,不继承主线程的事务上下文。
  • 异步线程中的异常不会影响主线程的事务状态。

    7. @Transactional 代理机制源码引导分析

  一旦分析源码,文章的可阅读性就降低了,这里留有有兴趣的小伙伴自行阅读。

  在 Spring 框架中,@Transactional 的代理机制主要涉及几个关键类和接口,包括 TransactionInterceptorProxyTransactionManagementConfigurationTransactionAttributeSourceAdvisorProxyFactoryBean 等。下面是一些关键的源码位置:

  TransactionInterceptor:这个类位于 org.springframework.transaction.interceptor 包中,它是事务管理的核心拦截器。

  TransactionAttributeSourceAdvisor:这个类位于 org.springframework.transaction.annotation 包中,它是 AOP Advisor,负责根据事务注解创建切点。

  ProxyTransactionManagementConfiguration:这个类位于 org.springframework.transaction.annotation 包中,它是事务管理配置的核心,负责注册事务管理相关的 bean

  可以从 @EnableTransactionManagement 注解开始追踪源码,该注解引导到 ProxyTransactionManagementConfiguration 类,该类配置了事务管理的 AOP 切面。



欢迎一键三连~



有问题请留言,大家一起探讨学习



----------------------Talk is cheap, show me the code-----------------------

目录
相关文章
|
12天前
|
存储 人工智能 弹性计算
阿里云弹性计算_加速计算专场精华概览 | 2024云栖大会回顾
2024年9月19-21日,2024云栖大会在杭州云栖小镇举行,阿里云智能集团资深技术专家、异构计算产品技术负责人王超等多位产品、技术专家,共同带来了题为《AI Infra的前沿技术与应用实践》的专场session。本次专场重点介绍了阿里云AI Infra 产品架构与技术能力,及用户如何使用阿里云灵骏产品进行AI大模型开发、训练和应用。围绕当下大模型训练和推理的技术难点,专家们分享了如何在阿里云上实现稳定、高效、经济的大模型训练,并通过多个客户案例展示了云上大模型训练的显著优势。
|
16天前
|
存储 人工智能 调度
阿里云吴结生:高性能计算持续创新,响应数据+AI时代的多元化负载需求
在数字化转型的大潮中,每家公司都在积极探索如何利用数据驱动业务增长,而AI技术的快速发展更是加速了这一进程。
|
7天前
|
并行计算 前端开发 物联网
全网首发!真·从0到1!万字长文带你入门Qwen2.5-Coder——介绍、体验、本地部署及简单微调
2024年11月12日,阿里云通义大模型团队正式开源通义千问代码模型全系列,包括6款Qwen2.5-Coder模型,每个规模包含Base和Instruct两个版本。其中32B尺寸的旗舰代码模型在多项基准评测中取得开源最佳成绩,成为全球最强开源代码模型,多项关键能力超越GPT-4o。Qwen2.5-Coder具备强大、多样和实用等优点,通过持续训练,结合源代码、文本代码混合数据及合成数据,显著提升了代码生成、推理和修复等核心任务的性能。此外,该模型还支持多种编程语言,并在人类偏好对齐方面表现出色。本文为周周的奇妙编程原创,阿里云社区首发,未经同意不得转载。
|
12天前
|
人工智能 运维 双11
2024阿里云双十一云资源购买指南(纯客观,无广)
2024年双十一,阿里云推出多项重磅优惠,特别针对新迁入云的企业和初创公司提供丰厚补贴。其中,36元一年的轻量应用服务器、1.95元/小时的16核60GB A10卡以及1元购域名等产品尤为值得关注。这些产品不仅价格亲民,还提供了丰富的功能和服务,非常适合个人开发者、学生及中小企业快速上手和部署应用。
|
2天前
|
云安全 存储 弹性计算
|
4天前
|
云安全 人工智能 自然语言处理
|
8天前
|
人工智能 自然语言处理 前端开发
用通义灵码,从 0 开始打造一个完整APP,无需编程经验就可以完成
通义灵码携手科技博主@玺哥超carry 打造全网第一个完整的、面向普通人的自然语言编程教程。完全使用 AI,再配合简单易懂的方法,只要你会打字,就能真正做出一个完整的应用。本教程完全免费,而且为大家准备了 100 个降噪蓝牙耳机,送给前 100 个完成的粉丝。获奖的方式非常简单,只要你跟着教程完成第一课的内容就能获得。
|
23天前
|
自然语言处理 数据可视化 前端开发
从数据提取到管理:合合信息的智能文档处理全方位解析【合合信息智能文档处理百宝箱】
合合信息的智能文档处理“百宝箱”涵盖文档解析、向量化模型、测评工具等,解决了复杂文档解析、大模型问答幻觉、文档解析效果评估、知识库搭建、多语言文档翻译等问题。通过可视化解析工具 TextIn ParseX、向量化模型 acge-embedding 和文档解析测评工具 markdown_tester,百宝箱提升了文档处理的效率和精确度,适用于多种文档格式和语言环境,助力企业实现高效的信息管理和业务支持。
3968 5
从数据提取到管理:合合信息的智能文档处理全方位解析【合合信息智能文档处理百宝箱】
|
12天前
|
算法 安全 网络安全
阿里云SSL证书双11精选,WoSign SSL国产证书优惠
2024阿里云11.11金秋云创季活动火热进行中,活动月期间(2024年11月01日至11月30日)通过折扣、叠加优惠券等多种方式,阿里云WoSign SSL证书实现优惠价格新低,DV SSL证书220元/年起,助力中小企业轻松实现HTTPS加密,保障数据传输安全。
535 3
阿里云SSL证书双11精选,WoSign SSL国产证书优惠
|
11天前
|
数据采集 人工智能 API
Qwen2.5-Coder深夜开源炸场,Prompt编程的时代来了!
通义千问团队开源「强大」、「多样」、「实用」的 Qwen2.5-Coder 全系列,致力于持续推动 Open Code LLMs 的发展。