2016-10-16 1 views
1

Я хотел бы измерить время транзакций, управляемых Spring, с помощью JpaTJpaTransactionManager/PlatformTransactionManager для обнаружения длительных ожидающих транзакций и предупреждения некоторых слушателей об этом состоянии.Можно ли измерить время всех транзакций, управляемых Spring, с помощью @Transactional?

Я мог бы использовать аспект на методах @Transactional, но из-за распространения транзакций это не очень хороший способ обнаружить, когда точная транзакция будет запущена или закончена.

Было бы хорошо, чтобы что-то вроде сделки слушателя с доступом, чтобы начать/закончить события вместе с каким-то именем боба объекта начиная операций Устанавливаются или просто трассировки стека

ответ

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

Uvoted, но я на самом деле подразумеваю общую транзакционную транзакцию для отслеживания медленных транзакций, а не для отслеживания каждой отдельной транзакции. Отредактированный вопрос. –

+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

Упрощение в качестве некоторого решения, но оригинальный вопрос касается механизма транзакций, поэтому он должен охватывать время транзакции, а также обрабатывать такие транзакции, как для .createNativeQuery или даже JDBC, если только они связаны с менеджером транзакций JPA. –

 Смежные вопросы

  • Нет связанных вопросов^_^