Spring事务失效,我总结了这7个主要原因

简介: 本文详细探讨了Spring事务在日常开发中常见的七个失效原因,包括数据库不支持事务、类不受Spring管理、事务方法非public、异常被捕获、`rollbackFor`属性配置错误、方法内部调用事务方法及事务传播属性使用不当。通过具体示例和源码分析,帮助开发者更好地理解和应用Spring事务机制,避免线上事故。适合所有使用Spring进行业务开发的工程师参考。

你好,我是猿java。

提起事务,很多人自然而然想到 MySQL数据库的 ACID,而 Spring Transaction 作为业务层的事务,也是Java日常开发中必不可少的。然而在工作中,很多开发认为只要在类或者方法上加上 @Transactional注解就可以万事大吉了,
殊不知事务失效的场景有多种,一个疏忽就可能造成了线上事故,这篇文章我来和你聊一聊导致Spring 事务失效的 7个主要原因,帮助你的日常工作避雷。

申明:本文是基于 Spring 5.3.21 版本,如果没有特殊说明,本文的数据库泛指 MySQL数据库

内容大纲:
img.png

1.数据库不支持事务

Spring 事务是业务层的事务,其底层还是依赖于数据库本身的事务支持。比如 MySQL 数据库,MyISAM 引擎不支持事务而 InnoDB 引擎支持事务。所以,开发中如果需要使用事务,一定要确保你选择的数据库支持事务。

MySQL数据库查看表信息指令如下,信息中包含表的使用的引擎类型:

show create table tablename\G

sql-transaction.png

从 MySQL 5.5.5版本开始,默认的数据库引擎已经从 MyISAM 更改成 InnoDB。所以,如果你的数据库低于这个版本,就得注意数据库或者表在创建的时候设置的引擎是 MyISAM 还是 InnoDB。

2.类不受 Spring管理

我们先看一段 Spring事务失效的代码:

// @Service
public class UserServiceImpl implements UserService {
   

    private final UserRepository userRepository;

    public UserServiceImpl(UserRepository userRepository) {
   
        this.userRepository = userRepository;
    }
    /* user{ "name": "name1", "age": 18 } */
    @Transactional
    @Override
    public void addUser(User user) {
   
        userRepository.save(user);
        // 模拟异常,数据库的记录应该回滚
        throw new RuntimeException();
    }
}

如上代码,将 UserServiceImpl类中的 @Service注解注释后,UserServiceImpl类就不受 Spring容器管理,导致事务失效!

事务为什么会失效?

这是因为 Spring事务是由 AOP机制实现的,AOP机制的本质就是动态代理,更直白的说:从 Spring IOC容器获取 bean时,Spring会为目标类创建代理,从而支持事务的,核心源码如下:

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
  implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
   

    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
   
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
   
            return bean;
        }
        if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
   
            return bean;
        }
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
   
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }

        // Create proxy if we have advice.
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        if (specificInterceptors != DO_NOT_PROXY) {
   
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
            // 创建 AOP代理
            Object proxy = createProxy(
                    bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }

        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

  protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
                               @Nullable Object[] specificInterceptors, TargetSource targetSource) {
   

    if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
   
      AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
    }

    ProxyFactory proxyFactory = new ProxyFactory();
    proxyFactory.copyFrom(this);
    // 部分代码省略
    // 创建 AOP 切面,将信息存放在代理中
    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    proxyFactory.addAdvisors(advisors);
    proxyFactory.setTargetSource(targetSource);
    customizeProxyFactory(proxyFactory);

    proxyFactory.setFrozen(this.freezeProxy);
    if (advisorsPreFiltered()) {
   
      proxyFactory.setPreFiltered(true);
    }
    // Use original ClassLoader if bean class not locally loaded in overriding class loader
    ClassLoader classLoader = getProxyClassLoader();
    if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
   
      classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
    }
    return proxyFactory.getProxy(classLoader);
  }
}

通过源码可以看出:事务需要的 Advisor等资源是在 Spring创建代理类时去创建的,因此,注释 UserServiceImpl类的 @Service注解,该类就不受 Spring容器管理,那么事务需要的 Advisor资源就无法生成,事务自然就失效了。

不过,需要说明的是,目前 Java业务开发几乎都采用了 Spring生态圈的框架,如果将 UserServiceImpl类的 @Service注解去掉:

假如 UserServiceImpl类是通过构造器注入到Controller层,则 IDEA会报错,编译通过不了,如下图:
spring-transaction-construct.png

假如 UserServiceImpl类是通过 @Autowired字段依赖注入,运行时会出现空指针异常,导致整个业务逻辑异常中断。

所以,"类不受 Spring管理"这个原因在现实开发中发生的概率比较低,但是该 case可以帮助我们更好的了解 Spring事务机制,所以被小编作为一个主要原因。

3.事务方法不是 public

假如对 UserServiceImpl类做部分修改,将事务方法 addUser()修改成 protected,代码如下:


@Service
public class UserServiceImpl /** implements UserService */{
   

    private final UserRepository userRepository;

    public UserServiceImpl(UserRepository userRepository) {
   
        this.userRepository = userRepository;
    }

    /* user{ "name": "name1", "age": 18 } */
    @Transactional
    //@Override
    protected void addUser(User user) {
   
        userRepository.save(user);
        // 模拟异常,数据库的记录应该回滚
        throw new RuntimeException();
    }
}

单测运行上面的代码,查询数据库中记录,如下图:

img.png

通过 client客户端查询user表数据发现:{ "name": "name1", "age": 18 } 记录存在数据库中,事务并未回滚,也就是事务失效了,不符合预期。

为什么事务会失效?

我们还是通过 Spring的官方核心源码来分析:

public abstract class AbstractFallbackTransactionAttributeSource
  implements TransactionAttributeSource, EmbeddedValueResolverAware {
   

  // 获取事务属性
  @Override
  @Nullable
  public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
   
      // 部分代码省略

      if (cached != null) {
   
        // 部分代码省略
      }
      else {
   
        // 调用 计算事务属性 方法
        // We need to work it out.
        TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
        // 部分代码省略
        return txAttr;
      }
  }

     // 计算事务属性
    @Nullable
    protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
   
        // 按照配置,不允许使用非公共方法。
        // Don't allow non-public methods, as configured.
        if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
   
            return null;
        }

        // 部分代码省略
        return null;
    }
}

通过源码,我们可以很清晰的看出,getTransactionAttribute()获取事务属性方法会调用 computeTransactionAttribute()方法,而computeTransactionAttribute()方法的逻辑,判断当方法非 public,则直接返回null,因此事务属性都不存在,事务自然也就不生效了。

4.异常被业务代码 catch

我们再对 UserServiceImpl类做代码调整,将 addUser()方法里的业务逻辑加上 try-catch,代码如下:


@Service
public class UserServiceImpl implements UserService {
   

    private final UserRepository userRepository;

    public UserServiceImpl(UserRepository userRepository) {
   
        this.userRepository = userRepository;
    }

    /* user{ "name": "name2", "age": 20 } */
    @Transactional
    @Override
    public void addUser(User user) {
   
       try{
   
         userRepository.save(user);
         // 模拟异常,数据库的记录应该回滚
         throw new RuntimeException();
       } catch (RuntimeException e) {
   
         log.error("addUser#error,user:{},e", user, e);
       }
    }
}

单测运行上面的代码,查询数据库中记录,如下图:
spring-transaction-try.png

通过 client客户端查询user表数据发现:{ "name": "name2", "age": 20 } 记录存在数据库中,并未回滚,也就是事务失效了,不符合预期。

为什么事务没有回滚?

我们依旧来看看 Spring的官方核心源码:

public abstract class TransactionAspectSupport implements BeanFactoryAware, InitializingBean {
   
  @Nullable
  protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
                                           final InvocationCallback invocation) throws Throwable {
   
      // 省略部分代码

      if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
   
          Object retVal;
          try {
   
              // This is an around advice: Invoke the next interceptor in the chain.
              // This will normally result in a target object being invoked.
              retVal = invocation.proceedWithInvocation();
          } catch (Throwable ex) {
   
              // target invocation exception
              // 回滚事务 是在 spring 的catch中处理,也就是说,如果Spring catch不到对应的异常,就不会进入回滚事务的逻辑
              completeTransactionAfterThrowing(txInfo, ex);
              throw ex;
          } finally {
   
              cleanupTransactionInfo(txInfo);
          }
          // 省略部分代码

          // 提交事务
          commitTransactionAfterReturning(txInfo);
          return retVal;
      }
  }

  /**
   * Handle a throwable, completing the transaction.
   * We may commit or roll back, depending on the configuration.
   * @param txInfo information about the current transaction
   * @param ex throwable encountered
   */
  protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {
   
    if (txInfo != null && txInfo.getTransactionStatus() != null) {
   
       // 省略部分代码
      if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {
   
        try {
   
            // 回滚事务
          txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
        }
        catch (TransactionSystemException ex2) {
   
          logger.error("Application exception overridden by rollback exception", ex);
          ex2.initApplicationException(ex);
          throw ex2;
        }
        catch (RuntimeException | Error ex2) {
   
          logger.error("Application exception overridden by rollback exception", ex);
          throw ex2;
        }
      }
        // 省略部分代码
    }
  }
}

通过源码,我们可以很清晰的看出,在 invokeWithinTransaction() 方法中,当 Spring catch到 Throwable异常,就会调用 completeTransactionAfterThrowing()方法进行事务回滚的逻辑。但是,在 UserServiceImpl类的业务代码中直接把异常catch住了,Spring自然就 catch不到异常,因此事务回滚的逻辑就不会执行,事务就失效了。

所以,在日常开发中,当我们在 try-catch做完一些常规操作(比如异常日志记录和监控打点)后,一定要记得把异常抛出来(特别注意抛出的异常一定要是 Throwable或其子类,原因在下文会分析),这样 Spring才能感知异常,回滚事务。

5.rollbackFor属性配置错误

我们接着对 UserServiceImpl类做修改,在 @Transactional注解里指定 rollbackFor属性,比如:@Transactional(rollbackFor = Error.class),代码如下:

@Service
public class UserServiceImpl implements UserService {
   

    private final UserRepository userRepository;

    public UserServiceImpl(UserRepository userRepository) {
   
        this.userRepository = userRepository;
    }

    /* user{ "name": "name3", "age": 30 } */
    @Transactional(rollbackFor = Error.class)
    @Override
    public void addUser(User user) {
   
      userRepository.save(user);
      // 模拟异常,数据库的记录应该回滚
      throw new Exception();
    }
}

单测运行上面的代码后,查询数据库中记录,如下图:

spring-transaction-rollback.png

通过 client客户端查询user表数据发现:{ "name": "name3", "age": 30 } 记录存在数据库中,并未回滚,也就是事务失效了,不符合预期。

为什么事务没有回滚?

我们依旧来看看 Spring的官方核心源码:


@Target({
   ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
   
  /**
   * Defines zero (0) or more exception classes, which must be subclasses of Throwable, indicating which exception types must cause a transaction rollback.
   * By default, a transaction will be rolled back on RuntimeException and Error but not on checked exceptions (business exceptions). See org.springframework.transaction.interceptor.DefaultTransactionAttribute.rollbackOn(Throwable) for a detailed explanation.
   * This is the preferred way to construct a rollback rule (in contrast to rollbackForClassName), matching the exception type, its subclasses, and its nested classes. See the class-level javadocs for further details on rollback rule semantics and warnings regarding possible unintentional matches.
   * @return
   */
  //  rollbackFor的异常必须是 Throwable的子类
  Class<? extends Throwable>[] rollbackFor() default {
   };
}

通过 Transactional注解源码,我们可以发现 rollbackFor属性指定的异常必须是 Throwable及其子类,并且在默认情况下,Spring对 RuntimeException 和 Error 两种异常会自动回滚事务,也就是说,如果业务抛出来的异常是 RuntimeException 和 Error类型,可以不需要通过 rollbackFor属性指定,Spring 默认会识别处理。

可是,UserServiceImpl类中 rollbackFor = Error.class,Error 明明是 Throwable的子类,为什么事务还是会失效?

这是因为,尽管业务代码指定了 rollbackFor = Error.class,但是代码中抛出的异常是 Exception(throw new Exception()),而 Exception 和 Error没有任何关系,也就是说,事务需要捕获到 Error才会回滚,可是你偏偏抛出一个和 Error不相关的 Exception异常,因此事务自然无效,不能回滚。

6.方法内部调用事务方法

我们接着对 UserServiceImpl类做修改,addUser()方法不加 @Transactional注解,而是在 addUser()内部调用一个加了 @Transactional注解的 doAddUser()方法,代码如下:

@Service
public class UserServiceImpl implements UserService {
   

    private final UserRepository userRepository;

    public UserServiceImpl(UserRepository userRepository) {
   
        this.userRepository = userRepository;
    }

  /* user{ "name": "name4", "age": 40 } */
  @Override
  public void addUser(User user){
   
    // 调用内部方法
    this.doAddUser(user);
  }

  @Transactional(rollbackFor = Error.class)
  public void doAddUser (User user){
   
    userRepository.save(user);
    // 模拟异常,数据库的记录应该回滚
    throw new RuntimeException();
  }
}

单测运行上面的代码,查询数据库中记录,如下图:

spring-transaction-inter.png

通过 client客户端查询user表数据发现:{ "name": "name4", "age": 40 } 记录存在数据库中,并未回滚,事务失效,不符合预期。

为什么事务没有回滚?

从上文"事务方法不是 public" 的分析可以知道,事务是通过Spring AOP代理来实现的,而 doAddUser()内部事务方法其实是this对象调用的,而不是通过AOP代理来调用的,因此事务失效。

7. 事务传播属性使用错误

我们最后对 UserServiceImpl类做修改,addUser()方法不加 @Transactional注解,而是在 addUser()内部调用一个加了 @Transactional注解的 doAddUser()方法,代码如下:

@Service
public class UserServiceImpl implements UserService {
   

    private final UserRepository userRepository;

    public UserServiceImpl(UserRepository userRepository) {
   
        this.userRepository = userRepository;
    }

  /* user{ "name": "name5", "age": 50 } */
  @Transactional(propagation = Propagation.SUPPORTS)
  @Override
  public void addUser(User user){
   
    this.doAddUser(user);
  }


  @Transactional
  public void doAddUser (User user){
   
    userRepository.save(user);
    throw new RuntimeException();
  }
}

单测运行上面的代码,查询数据库中记录,如下图:

spring-transaction-propagation.png

通过 client客户端查询user表数据发现:{ "name": "name5", "age": 50 } 记录存在数据库中,并未回滚,事务失效,不符合预期。

为什么事务没有回滚?

我们还是从 Spring源码来找原因:

@Target({
   ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
   
  /**
   * The transaction propagation type.
   * <p>Defaults to {@link Propagation#REQUIRED}.
   * @see org.springframework.transaction.interceptor.TransactionAttribute#getPropagationBehavior()
   */
  Propagation propagation() default Propagation.REQUIRED;
}

public enum Propagation {
   

  /**
   * Support a current transaction, create a new one if none exists.
   * Analogous to EJB transaction attribute of the same name.
   * <p>This is the default setting of a transaction annotation.
   */
  REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),

  /**
   * Support a current transaction, execute non-transactionally if none exists.
   * Analogous to EJB transaction attribute of the same name.
   * <p>Note: For transaction managers with transaction synchronization,
   * {@code SUPPORTS} is slightly different from no transaction at all,
   * as it defines a transaction scope that synchronization will apply for.
   * As a consequence, the same resources (JDBC Connection, Hibernate Session, etc)
   * will be shared for the entire specified scope. Note that this depends on
   * the actual synchronization configuration of the transaction manager.
   * @see org.springframework.transaction.support.AbstractPlatformTransactionManager#setTransactionSynchronization
   */
  SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),

  /**
   * Support a current transaction, throw an exception if none exists.
   * Analogous to EJB transaction attribute of the same name.
   */
  MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),

  /**
   * Create a new transaction, and suspend the current transaction if one exists.
   * Analogous to the EJB transaction attribute of the same name.
   * <p><b>NOTE:</b> Actual transaction suspension will not work out-of-the-box
   * on all transaction managers. This in particular applies to
   * {@link org.springframework.transaction.jta.JtaTransactionManager},
   * which requires the {@code javax.transaction.TransactionManager} to be
   * made available to it (which is server-specific in standard Java EE).
   * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager
   */
  REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),

  /**
   * Execute non-transactionally, suspend the current transaction if one exists.
   * Analogous to EJB transaction attribute of the same name.
   * <p><b>NOTE:</b> Actual transaction suspension will not work out-of-the-box
   * on all transaction managers. This in particular applies to
   * {@link org.springframework.transaction.jta.JtaTransactionManager},
   * which requires the {@code javax.transaction.TransactionManager} to be
   * made available to it (which is server-specific in standard Java EE).
   * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager
   */
  NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),

  /**
   * Execute non-transactionally, throw an exception if a transaction exists.
   * Analogous to EJB transaction attribute of the same name.
   */
  NEVER(TransactionDefinition.PROPAGATION_NEVER),

  /**
   * Execute within a nested transaction if a current transaction exists,
   * behave like {@code REQUIRED} otherwise. There is no analogous feature in EJB.
   * <p>Note: Actual creation of a nested transaction will only work on specific
   * transaction managers. Out of the box, this only applies to the JDBC
   * DataSourceTransactionManager. Some JTA providers might support nested
   * transactions as well.
   * @see org.springframework.jdbc.datasource.DataSourceTransactionManager
   */
  NESTED(TransactionDefinition.PROPAGATION_NESTED);


  private final int value;


  Propagation(int value) {
   
    this.value = value;
  }

  public int value() {
   
    return this.value;
  }

}

从源码中我们可以得知,Spring事务默认的事务传播机制是:REQUIRED,我们先对 Propagation类中 Spring事务传播机制进行总结:

  1. PROPAGATION_REQUIRED:要求使用事务,如果当前没有事务,则创建一个新的事务,如果当前存在事务,就加入该事务,该设置是默认也是最常用的设置。
  2. PROPAGATION_SUPPORTS:支持使用事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。‘
  3. PROPAGATION_MANDATORY:强制使用事务,如果当前存在事务,就加入该事务,如果当前不存在事务,则抛出异常。
  4. PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。
  5. PROPAGATION_NOT_SUPPORTED:不支持事务,如果当前存在事务,就把当前事务挂起。
  6. PROPAGATION_NEVER:不允许使用事务,如果当前存在事务,则抛出异常。
  7. PROPAGATION_NESTED:内嵌事务,如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则按REQUIRED属性执行。

上述 addUser()方法的事务传播机制是 Propagation.SUPPORTS,也就是当前方法有事务就假如事务,不存在事务则以非事务执行,因为 addUser()方法不存在事务,所以该方法就以非事务执行,因此事务失效。

此案例是典型的 Spring事务传播机制使用错误,我们只需要将 @Transactional(propagation = Propagation.SUPPORTS) 修改成 @Transactional(propagation = Propagation.REQUIRED),事务就可以生效了。

总结

本文列举了日常开发中 Spring事务失效常见的7个主要原因,通过分析我们可以发现,事务失效的大部分原因是对 Spring的运行机制不够了解。或许在开发中大家还会遇到其他形形色色的原因,但不管怎样,只要我们能去认真去分析 Spring事务相关的源码,很多问题就迎刃而解。

学习交流

如果你觉得文章有帮助,请帮忙转发给更多的好友,或关注:猿java,持续输出硬核文章。

目录
相关文章
|
23天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
15天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
20天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2572 22
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
18天前
|
人工智能 IDE 程序员
期盼已久!通义灵码 AI 程序员开启邀测,全流程开发仅用几分钟
在云栖大会上,阿里云云原生应用平台负责人丁宇宣布,「通义灵码」完成全面升级,并正式发布 AI 程序员。
|
3天前
|
JSON 自然语言处理 数据管理
阿里云百炼产品月刊【2024年9月】
阿里云百炼产品月刊【2024年9月】,涵盖本月产品和功能发布、活动,应用实践等内容,帮助您快速了解阿里云百炼产品的最新动态。
阿里云百炼产品月刊【2024年9月】
|
2天前
|
存储 人工智能 搜索推荐
数据治理,是时候打破刻板印象了
瓴羊智能数据建设与治理产品Datapin全面升级,可演进扩展的数据架构体系为企业数据治理预留发展空间,推出敏捷版用以解决企业数据量不大但需构建数据的场景问题,基于大模型打造的DataAgent更是为企业用好数据资产提供了便利。
159 2
|
19天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1570 16
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
|
21天前
|
编解码 JSON 自然语言处理
通义千问重磅开源Qwen2.5,性能超越Llama
击败Meta,阿里Qwen2.5再登全球开源大模型王座
944 14
|
3天前
|
Linux 虚拟化 开发者
一键将CentOs的yum源更换为国内阿里yum源
一键将CentOs的yum源更换为国内阿里yum源
187 2
|
16天前
|
人工智能 开发框架 Java
重磅发布!AI 驱动的 Java 开发框架:Spring AI Alibaba
随着生成式 AI 的快速发展,基于 AI 开发框架构建 AI 应用的诉求迅速增长,涌现出了包括 LangChain、LlamaIndex 等开发框架,但大部分框架只提供了 Python 语言的实现。但这些开发框架对于国内习惯了 Spring 开发范式的 Java 开发者而言,并非十分友好和丝滑。因此,我们基于 Spring AI 发布并快速演进 Spring AI Alibaba,通过提供一种方便的 API 抽象,帮助 Java 开发者简化 AI 应用的开发。同时,提供了完整的开源配套,包括可观测、网关、消息队列、配置中心等。
711 10