You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用@Modifying+@Query执行DELETE查询遇TransactionRequiredException求助

解决TransactionRequiredException执行DELETE查询的问题

这个错误的核心原因很明确:你在执行DELETE这类修改数据的操作时,没有处于一个活跃的数据库事务中。Spring Data JPA的默认规则是:只有查询类方法会自动纳入只读事务,而UPDATE/DELETE这类变更数据的操作,必须显式声明事务支持才能执行。

下面给你几种可行的解决方案,按推荐程度排序:


方案1:直接在Repository方法上添加@Transactional注解

最简单的处理方式就是给你的deleteContributeur方法加上Spring的@Transactional注解。这样Spring会为这个方法单独开启一个事务,执行完成后自动提交,完全覆盖你需要的DELETE操作场景。

修改后的代码示例:

import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.jpa.repository.Param;
import org.springframework.data.repository.CrudRepository;

public interface CustomerRepository extends CrudRepository<Customer, Long> {

    @Modifying
    @Transactional // 添加这个事务注解
    @Query(value = "DELETE FROM CUSTOMERS where CUSTOMERS.ID =:customersId and CUSTOMERS.USER_ID = :userId and CUSTOMERS.USER_ID = :sellerId", nativeQuery = true)
    void deleteContributeur(@Param("customersId") Long customersId, @Param("userId") Long userId, @Param("sellerId") Long sellerId);
}

方案2:在业务层(Service)方法上添加@Transactional

如果你的Repository方法是被Service层调用的,更推荐把事务注解加在Service的业务方法上。这样可以让事务覆盖整个业务逻辑流程(比如删除前后的参数校验、日志记录等操作),符合分层架构的最佳实践。

示例Service层代码:

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class CustomerService {

    private final CustomerRepository customerRepository;

    // 构造注入(Spring推荐的依赖注入方式)
    public CustomerService(CustomerRepository customerRepository) {
        this.customerRepository = customerRepository;
    }

    @Transactional // 事务注解放在业务方法上
    public void removeContributeur(Long customersId, Long userId, Long sellerId) {
        // 这里可以添加额外业务逻辑,比如参数合法性校验
        customerRepository.deleteContributeur(customersId, userId, sellerId);
    }
}

额外小提醒:检查SQL逻辑

顺便提一句,你的DELETE语句里有个潜在的逻辑问题:CUSTOMERS.USER_ID = :userId and CUSTOMERS.USER_ID = :sellerId。这要求USER_ID必须同时等于userId和sellerId两个参数的值,只有当这两个参数完全相同时才会匹配到记录。如果这不是你的业务预期,可能需要改成OR或者调整条件哦。


内容的提问来源于stack exchange,提问作者Aaron Guilbot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:36:00