簡體   English   中英

如何在事務開始之前或提交之前執行操作?

[英]How to perform an operation before a transaction is started of before it is committed?

在事務提交之前,我必須在一個特殊的全局臨時表中執行插入操作。

這是由於舊的數據庫設計使用此表在每個業務表上使用觸發器執行審計操作。 另一個用 C 編寫的軟件使用這種模式來執行對代碼影響很小的審計:

  • 建立連接時在臨時表中插入審計數據
  • 執行各種插入/更新,觸發器會將這些操作與審計數據聯系起來
  • 提交:審計日期從臨時表中刷新

現在我有一個 Spring Boot + JPA (Hibernate) 應用程序開始使用相同的數據庫,我需要重現這種模式。 然而,對於事務的 Spring + JPA 抽象,我很難找到一種方法來復制這種行為。

我需要在創建事務時(或在提交之前)執行審計數據的插入。 我已經檢查了這個有希望的TransactionalEventListener ,但看起來我必須聲明一個發布者並在每個服務中手動觸發事件, 如下例所示

@Service
public class CustomerService {
    private final CustomerRepository customerRepository;
    private final ApplicationEventPublisher applicationEventPublisher;
    public CustomerService(CustomerRepository customerRepository, ApplicationEventPublisher applicationEventPublisher) {
        this.customerRepository = customerRepository;
        this.applicationEventPublisher = applicationEventPublisher;
    }
    @Transactional
    public Customer createCustomer(String name, String email) {
        final Customer newCustomer = customerRepository.save(new Customer(name, email));
        final CustomerCreatedEvent event = new CustomerCreatedEvent(newCustomer);
        applicationEventPublisher.publishEvent(event);
        return newCustomer;
    }
}

正如您在此示例中看到的,服務聲明了一個ApplicationEventPublisher並需要調用applicationEventPublisher.publishEvent(event); 每次更新/插入后。

這不能滿足我的需求:我確實需要能夠在每次 commit() 之前執行此操作,並且這對於所有服務和存儲庫都必須是自動的。

我已經開始研究基於 AOP 的解決方案,但我覺得它有點矯枉過正。

那么在 Spring Boot + JAP 上下文中的任何提交之前,是否有任何簡單的解決方案可以執行一些操作?

JPA為您提供事件監聽工具。

您可以使用 @EntityListener(YourListener.class) 注釋標記您的實體:

@Entity
@EntityListeners(YourListener.class)
...
public class Entity implements Persistable<>

YourListener 應該是這樣的:

public class YourListener<T extends Persistable> {
    @PostUpdate
    public void onPostPersist(T entity) {
        //do
    }
}

幾個注解來標記監聽器的方法,您可以選擇以下鈎子:@(PrePersits/PreUpdate/PreRemove/PostPersits/PostUpdate/PostRemove/PostLoad)。

確保在執行偵聽器期間不要使用相同的 EntityManager 來節省任何額外費用,請參閱https://stackoverflow.com/a/42222592/5661496和其他答案。

我個人最終開始使用新的 Hibernate session 以防我需要將數據保存在另一個實體中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM