在同一個類中調(diào)用帶有@Transactional注解的方法示例
將調(diào)用方法和被調(diào)用方法分開
分別使用 @Transactional 注解來管理事務(wù)
推薦這個方法\color{red}{推薦這個方法}推薦這個方法
@Service
@Transactional
public class MyService {
@Autowired
private MyRepository myRepository;
public void foo() {
// 在此調(diào)用 bar 方法,事務(wù)將自動傳播
bar();
}
public void bar() {
// 這里是被調(diào)用的方法,也添加 @Transactional 注解來管理事務(wù)
myRepository.save(new MyEntity());
}
}
使用 AspectJ 的方式
- 在同一個類中通過調(diào)用代理對象的方式來保證事務(wù)生效。
需要注意的是,使用 AopContext.currentProxy() 需要開啟 Spring 的 AspectJ 支持,
@Service
@Transactional
public class MyService {
@Autowired
private MyRepository myRepository;
public void foo() {
// 在此調(diào)用 bar 方法,事務(wù)將生效
((MyService) AopContext.currentProxy()).bar();
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
private void bar() {
// 這里是被調(diào)用的方法,使用 REQUIRES_NEW 傳播行為開啟一個新的事務(wù)
myRepository.save(new MyEntity());
}
}- 在同一個類中注入自身實例,并通過這個實例調(diào)用被調(diào)用方法,保證事務(wù)生效。
需要注意的是,這種方式雖然可以保證事務(wù)生效,但是需要在同一個類中注入自己,不太符合面向?qū)ο蟮脑O(shè)計原則
@Service
@Transactional
public class MyService {
@Autowired
private MyRepository myRepository;
@Autowired
private MyService self;
public void foo() {
// 在此調(diào)用 bar 方法,事務(wù)將自動傳播
self.bar();
}
public void bar() {
// 這里是被調(diào)用的方法,也添加 @Transactional 注解來管理事務(wù)
myRepository.save(new MyEntity());
}
}
使用 Spring 提供的 TransactionTemplate
- 在同一個類中通過編程式事務(wù)處理的方式來保證事務(wù)生效。
@Service
@Transactional
public class MyService {
@Autowired
private MyRepository myRepository;
@Autowired
private TransactionTemplate transactionTemplate;
public void foo() {
// 在此調(diào)用 bar 方法,事務(wù)將生效
transactionTemplate.execute(new TransactionCallback<Void>() {
@Override
public Void doInTransaction(TransactionStatus status) {
// 在此執(zhí)行需要在事務(wù)中完成的邏輯
myRepository.save(new MyEntity());
return null;
}
});
}
}其中,MyRepository 是一個 JPA Repository 接口,用于操作數(shù)據(jù)庫;MyEntity 是一個實體類,代表一個數(shù)據(jù)庫表。
使用Spring的AOP功能來保證事務(wù)生效。
在同一個類中調(diào)用方法時,因為沒有經(jīng)過Spring代理,所以無法使用 @Transactional 注解來管理事務(wù)。但是,可以使用AspectJ的注解方式來實現(xiàn)事務(wù)的控制。
下面是一個示例代碼,用于在同一個類中調(diào)用方法時,保證事務(wù)生效:
@Component
@Aspect
public class TransactionalAspect {
@Autowired
private PlatformTransactionManager transactionManager;
@Pointcut("@annotation(org.springframework.transaction.annotation.Transactional)")
public void transactionalMethod() {}
@Around("transactionalMethod()")
public Object manageTransaction(ProceedingJoinPoint pjp) throws Throwable {
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
definition.setName(pjp.getSignature().getName());
definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
TransactionStatus status = transactionManager.getTransaction(definition);
try {
Object result = pjp.proceed();
transactionManager.commit(status);
return result;
} catch (Throwable t) {
transactionManager.rollback(status);
throw t;
}
}
}
上述示例代碼中,定義了一個名為TransactionalAspect的切面類,使用@Aspect注解進行標(biāo)注。在切面類中,定義了一個名為transactionalMethod的切點,用于匹配所有使用@Transactional注解標(biāo)記的方法。
在manageTransaction方法中,使用TransactionTemplate手動開啟一個新的事務(wù),并在事務(wù)中執(zhí)行被調(diào)用的方法。如果被調(diào)用的方法執(zhí)行成功,則提交事務(wù);如果被調(diào)用的方法發(fā)生異常,則回滾事務(wù)。
需要注意的是,這種方式雖然可以實現(xiàn)事務(wù)的控制,但是需要手動管理事務(wù),增加了代碼的復(fù)雜度和維護成本。因此,建議將調(diào)用方法和被調(diào)用方法分開,使用 @Transactional 注解來管理事務(wù),以便更好地維護和管理代碼。
以上就是在同一個類中調(diào)用帶有@Transactional注解的方法示例的詳細內(nèi)容,更多關(guān)于類調(diào)用@Transactional注解的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Spring Boot 3.x 全新的熱部署配置方式詳解(IntelliJ ID
這篇文章主要介紹了Spring Boot 3.x 全新的熱部署配置方式(IntelliJ IDEA 2023.1),本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-07-07
Java 使用Axis調(diào)用WebService的示例代碼
這篇文章主要介紹了Java 使用Axis調(diào)用WebService的示例代碼,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下2020-09-09
SpringCloud之熔斷器Hystrix的實現(xiàn)
這篇文章主要介紹了SpringCloud之熔斷器Hystrix的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08
詳解springmvc之json數(shù)據(jù)交互controller方法返回值為簡單類型
這篇文章主要介紹了springmvc之json數(shù)據(jù)交互controller方法返回值為簡單類型,非常具有實用價值,需要的朋友可以參考下2017-05-05
SpringBoot中使用websocket出現(xiàn)404的解決方法
在Springboot中使用websocket時,本地開發(fā)環(huán)境可以正常運行,但部署到服務(wù)器環(huán)境出現(xiàn)404問題,所以本文小編講給大家詳細介紹一下SpringBoot中使用websocket出現(xiàn)404的解決方法,需要的朋友可以參考下2023-09-09

