2016-10-16 14 views
1

我想通過JpaTJpaTransactionManager/PlatformTransactionManager來測量Spring管理的交易時間,以檢測長期掛起的交易並警告一些聽衆關於該情況。有沒有可能使用@Transactional來衡量所有Spring管理事務的時間?

我可以在@Transactional方法上使用方面,但由於事務傳播,它不是一個很好的方法來檢測確切的事務何時開始或完成。

這將是很好的類似交易監聽器訪問與對象的一些bean的名字開始/結束事件一起開始trasaction或只是一個堆棧跟蹤

回答

3

使用TransactionSynchronizationManager標註的方法中:

TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization(){ 

     long startTime; 

     void beforeCommit() { 
      startTime = System.nanoTime(); 
     } 
     void afterCommit(){ 
      System.out.println("Transaction time: " + (System.nanoTime() - startTime)); 
     } 
}); 

跟蹤所有方面事務:

@Aspect 
class TransactionAspect extends TransactionSynchronizationAdapter { 

    @Before("@annotation(org.springframework.transaction.annotation.Transactional)") 
    public void registerTransactionSyncrhonization() { 
     TransactionSynchronizationManager.registerSynchronization(this); 

    } 

    ThreadLocal<Long> startTime = new ThreadLocal<>(); 

    void beforeCommit() { 
     startTime.set(System.nanoTime()); 
    } 
    void afterCommit(){ 
     System.out.println("Transaction time: " + (System.nanoTime() - startTime.get())); 
    } 
} 
+0

已投票但我實際上是指一般交易記錄,以跟蹤緩慢的交易,而不是明確跟蹤每筆交易。編輯的問題。 –

+0

@PiotrMüller使用方面。 –

1

您可以考慮實施一個實現ApplicationListener<E extends ApplicationEvent>類和執行在那裏測量。事情是這樣的:

@Component 
public class TransactionListener implements ApplicationListener<Neo4jDataManipulationEvent> { 

    private Long transactionStart; 
    private static final Logger log = LoggerFactory.getLogger(TransactionListener.class); 

    @Override 
    public void onApplicationEvent(Neo4jDataManipulationEvent event) { 
     if (event instanceof BeforeSaveEvent) { 
      transactionStart = System.currentTimeMillis(); 
     } 
     if (event instanceof AfterSaveEvent) { 
      log.debug("Transaction time in ms: ", System.currentTimeMillis() - transactionStart); 
      log.debug("Source: ", event.getSource()); 
     } 
    } 

對於JPA可以考慮實施類似的解決方案(根據this tutorial):

public class LogListener { 

    private Long transactionStart; 

    @PrePersist 
    @PreUpdate 
    @PreRemove 
    private void before(Object object) { 
     transactionStart = System.currentTimeMillis(); 
    } 

    @PostPersist 
    @PostUpdate 
    @PostRemove 
    private void after(Object object) { 
     System.out.println("Transaction time in ms: ", System.currentTimeMillis() - transactionStart); 
     System.out.println("Source: ", object.getClass()); 
    } 

} 

您需要標註哪些實例被保存到數據庫與@EntityListeners(LogListener.class)實體類之後。

+0

JPA是否發出這樣的事務性事件? –

+0

@PiotrMüller我編輯了我的答案。讓我知道這是否適合你。但是,idk如何通過這種方式來衡量閱讀交易時間。 – Polyakoff

+0

Upvotes作爲一些解決方案,但原來的問題是交易機制,所以它應該跨越交易時間,並且還處理像.createNativeQuery甚至JDBC這樣的轉換,如果只是由JPA事務管理器跨越。 –

相關問題