您好,登錄后才能下訂單哦!
這篇文章主要介紹“怎么在同一個類中調用帶有@Transactional注解”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“怎么在同一個類中調用帶有@Transactional注解”文章能幫助大家解決問題。
分別使用 @Transactional 注解來管理事務
推薦這個方法\color{red}{推薦這個方法}推薦這個方法
@Service @Transactional public class MyService { @Autowired private MyRepository myRepository; public void foo() { // 在此調用 bar 方法,事務將自動傳播 bar(); } public void bar() { // 這里是被調用的方法,也添加 @Transactional 注解來管理事務 myRepository.save(new MyEntity()); } }
在同一個類中通過調用代理對象的方式來保證事務生效。
需要注意的是,使用 AopContext.currentProxy() 需要開啟 Spring 的 AspectJ 支持,
@Service @Transactional public class MyService { @Autowired private MyRepository myRepository; public void foo() { // 在此調用 bar 方法,事務將生效 ((MyService) AopContext.currentProxy()).bar(); } @Transactional(propagation = Propagation.REQUIRES_NEW) private void bar() { // 這里是被調用的方法,使用 REQUIRES_NEW 傳播行為開啟一個新的事務 myRepository.save(new MyEntity()); } }
在同一個類中注入自身實例,并通過這個實例調用被調用方法,保證事務生效。
需要注意的是,這種方式雖然可以保證事務生效,但是需要在同一個類中注入自己,不太符合面向對象的設計原則
@Service @Transactional public class MyService { @Autowired private MyRepository myRepository; @Autowired private MyService self; public void foo() { // 在此調用 bar 方法,事務將自動傳播 self.bar(); } public void bar() { // 這里是被調用的方法,也添加 @Transactional 注解來管理事務 myRepository.save(new MyEntity()); } }
在同一個類中通過編程式事務處理的方式來保證事務生效。
@Service @Transactional public class MyService { @Autowired private MyRepository myRepository; @Autowired private TransactionTemplate transactionTemplate; public void foo() { // 在此調用 bar 方法,事務將生效 transactionTemplate.execute(new TransactionCallback<Void>() { @Override public Void doInTransaction(TransactionStatus status) { // 在此執行需要在事務中完成的邏輯 myRepository.save(new MyEntity()); return null; } }); } }
其中,MyRepository 是一個 JPA Repository 接口,用于操作數據庫;MyEntity 是一個實體類,代表一個數據庫表。
在同一個類中調用方法時,因為沒有經過Spring代理,所以無法使用 @Transactional 注解來管理事務。但是,可以使用AspectJ的注解方式來實現事務的控制。
下面是一個示例代碼,用于在同一個類中調用方法時,保證事務生效:
@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注解進行標注。在切面類中,定義了一個名為transactionalMethod的切點,用于匹配所有使用@Transactional注解標記的方法。
在manageTransaction方法中,使用TransactionTemplate手動開啟一個新的事務,并在事務中執行被調用的方法。如果被調用的方法執行成功,則提交事務;如果被調用的方法發生異常,則回滾事務。
需要注意的是,這種方式雖然可以實現事務的控制,但是需要手動管理事務,增加了代碼的復雜度和維護成本。因此,建議將調用方法和被調用方法分開,使用 @Transactional 注解來管理事務,以便更好地維護和管理代碼。
關于“怎么在同一個類中調用帶有@Transactional注解”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。