Skip to main content

springboot-transaction


slug: /springboot-transaction title: springboot-transaction需要跨类 tags: [springboot, usage]

date: 2024-04-17

@Transational使用

IDE报错: @Transactional 自调用(实际上是目标对象内的方法调用目标对象的另一个方法)在运行时不会导致实际的事务

咨询chatgpt:

在使用 @Transactional 注解时,自调用(即目标对象内的方法调用目标对象的另一个方法)可能不会触发实际的事务。这是因为 Spring 的事务管理是基于代理模式实现的。

当你在目标对象内部调用另一个方法时,实际上是通过目标对象的引用直接调用的,并没有经过代理对象。因此,代理对象无法拦截这个内部调用,从而无法应用事务的切面。

为了解决这个问题,你可以将自调用的方法提取到一个单独的类中,并通过依赖注入的方式在目标对象中使用。这样,Spring 将会通过代理对象来调用这个方法,从而触发事务的切面。

以下是一个示例,展示了如何在自调用方法上应用事务:

@Service
@Transactional
public class MyService {

@Autowired
private AnotherService anotherService;

public void myMethod() {
// 调用另一个类的方法
anotherService.anotherMethod();
}
}

@Service
public class AnotherService {

@Transactional
public void anotherMethod() {
// 执行逻辑
}
}

在上述示例中,MyService 类中的 myMethod() 方法调用了 AnotherService 类中的 anotherMethod() 方法。为了确保事务生效,我们在 AnotherService 类的 anotherMethod() 方法上添加了 @Transactional 注解。

通过这种方式,当 myMethod() 方法被调用时,Spring 将会通过代理对象调用 anotherMethod() 方法,并应用事务的切面。

希望这个解释对你有帮助!如果你还有其他问题,请随时提问。

transaction的调用链里开启新的事务

    @Transactional(propagation = Propagation.REQUIRES_NEW)
public void updateRevokeRecords(String jobId, SecurityAuthorityRevokeRequest request,
List<ResourceResult> results)

还是咨询chatgpt得到的答案

在 MyBatis 和 Spring Boot 中,如果你想在一个 @Transactional 注解的方法中调用另一个 @Transactional 注解的方法,并且希望在调用的方法中开启一个新的事务,可以使用 Spring 的编程式事务管理。

首先,确保你的项目中已经配置了事务管理器(例如,使用 Spring 的 DataSourceTransactionManager)以及开启了对 @Transactional 注解的支持。

然后,你可以使用 Spring 的 TransactionTemplate 类来手动管理事务。以下是一个示例,展示了如何在 MyBatis 和 Spring Boot 中配置和使用 TransactionTemplate

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

@Service
public class MyService {

@Autowired
private TransactionTemplate transactionTemplate;

@Autowired
private MyMapper myMapper;

@Transactional
public void outerMethod() {
transactionTemplate.execute(new TransactionCallback<Void>() {
@Override
public Void doInTransaction(TransactionStatus status) {
innerMethod();
return null;
}
});
}

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void innerMethod() {
// 执行 MyBatis 操作
}
}