在同一個(gè)類中調(diào)用帶有@Transactional注解的方法示例
將調(diào)用方法和被調(diào)用方法分開(kāi)
分別使用 @Transactional 注解來(lái)管理事務(wù)
推薦這個(gè)方法\color{red}{推薦這個(gè)方法}推薦這個(gè)方法
@Service
@Transactional
public class MyService {
@Autowired
private MyRepository myRepository;
public void foo() {
// 在此調(diào)用 bar 方法,事務(wù)將自動(dòng)傳播
bar();
}
public void bar() {
// 這里是被調(diào)用的方法,也添加 @Transactional 注解來(lái)管理事務(wù)
myRepository.save(new MyEntity());
}
}
使用 AspectJ 的方式
- 在同一個(gè)類中通過(guò)調(diào)用代理對(duì)象的方式來(lái)保證事務(wù)生效。
需要注意的是,使用 AopContext.currentProxy() 需要開(kāi)啟 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 傳播行為開(kāi)啟一個(gè)新的事務(wù)
myRepository.save(new MyEntity());
}
}- 在同一個(gè)類中注入自身實(shí)例,并通過(guò)這個(gè)實(shí)例調(diào)用被調(diào)用方法,保證事務(wù)生效。
需要注意的是,這種方式雖然可以保證事務(wù)生效,但是需要在同一個(gè)類中注入自己,不太符合面向?qū)ο蟮脑O(shè)計(jì)原則
@Service
@Transactional
public class MyService {
@Autowired
private MyRepository myRepository;
@Autowired
private MyService self;
public void foo() {
// 在此調(diào)用 bar 方法,事務(wù)將自動(dòng)傳播
self.bar();
}
public void bar() {
// 這里是被調(diào)用的方法,也添加 @Transactional 注解來(lái)管理事務(wù)
myRepository.save(new MyEntity());
}
}
使用 Spring 提供的 TransactionTemplate
- 在同一個(gè)類中通過(guò)編程式事務(wù)處理的方式來(lái)保證事務(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 是一個(gè) JPA Repository 接口,用于操作數(shù)據(jù)庫(kù);MyEntity 是一個(gè)實(shí)體類,代表一個(gè)數(shù)據(jù)庫(kù)表。
使用Spring的AOP功能來(lái)保證事務(wù)生效。
在同一個(gè)類中調(diào)用方法時(shí),因?yàn)闆](méi)有經(jīng)過(guò)Spring代理,所以無(wú)法使用 @Transactional 注解來(lái)管理事務(wù)。但是,可以使用AspectJ的注解方式來(lái)實(shí)現(xiàn)事務(wù)的控制。
下面是一個(gè)示例代碼,用于在同一個(gè)類中調(diào)用方法時(shí),保證事務(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;
}
}
}
上述示例代碼中,定義了一個(gè)名為TransactionalAspect的切面類,使用@Aspect注解進(jìn)行標(biāo)注。在切面類中,定義了一個(gè)名為transactionalMethod的切點(diǎn),用于匹配所有使用@Transactional注解標(biāo)記的方法。
在manageTransaction方法中,使用TransactionTemplate手動(dòng)開(kāi)啟一個(gè)新的事務(wù),并在事務(wù)中執(zhí)行被調(diào)用的方法。如果被調(diào)用的方法執(zhí)行成功,則提交事務(wù);如果被調(diào)用的方法發(fā)生異常,則回滾事務(wù)。
需要注意的是,這種方式雖然可以實(shí)現(xiàn)事務(wù)的控制,但是需要手動(dòng)管理事務(wù),增加了代碼的復(fù)雜度和維護(hù)成本。因此,建議將調(diào)用方法和被調(diào)用方法分開(kāi),使用 @Transactional 注解來(lái)管理事務(wù),以便更好地維護(hù)和管理代碼。
以上就是在同一個(gè)類中調(diào)用帶有@Transactional注解的方法示例的詳細(xì)內(nèi)容,更多關(guān)于類調(diào)用@Transactional注解的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
詳解Java內(nèi)部類與對(duì)象的打印概念和流程
在 Java 中,可以將一個(gè)類定義在另一個(gè)類里面或者一個(gè)方法里面,這樣的類稱為內(nèi)部類。廣泛意義上的內(nèi)部類一般來(lái)說(shuō)包括這四種:成員內(nèi)部類、局部?jī)?nèi)部類、匿名內(nèi)部類和靜態(tài)內(nèi)部類2021-10-10
MyBatis分頁(yè)查詢返回list的時(shí)候出現(xiàn)null的問(wèn)題
這篇文章主要介紹了MyBatis分頁(yè)查詢返回list的時(shí)候出現(xiàn)null的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07
IntelliJ IDEA(或者JetBrains PyCharm)中彈出"IntelliJ IDEA License
今天小編就為大家分享一篇關(guān)于IntelliJ IDEA(或者JetBrains PyCharm)中彈出"IntelliJ IDEA License Activation"的解決辦法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-10-10
在Spring項(xiàng)目中引入高版本依賴并解決低版本沖突問(wèn)題的解決方法
在Spring項(xiàng)目的開(kāi)發(fā)過(guò)程中,依賴管理是一個(gè)非常重要且復(fù)雜的問(wèn)題,我們可能需要引入更高版本的依賴來(lái)使用新特性或修復(fù)舊版本的Bug,然而,這些高版本依賴可能會(huì)與項(xiàng)目中已有的低版本依賴產(chǎn)生沖突,本文將詳細(xì)探討如何在Spring中引入高版本依賴,并解決低版本依賴沖突的問(wèn)題2025-03-03
Java利用cors實(shí)現(xiàn)跨域請(qǐng)求實(shí)例
本篇文章主要介紹了Java利用cors實(shí)現(xiàn)跨域請(qǐng)求實(shí)例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-05-05
Java 獲取服務(wù)器環(huán)境的實(shí)例詳解
這篇文章主要介紹了Java 獲取服務(wù)器環(huán)境的實(shí)例詳解的相關(guān)資料,這里提供實(shí)例和輸出結(jié)果,希望能幫助大家理解,需要的朋友可以參考下2017-07-07

