簡體   English   中英

Spring @Transactional 不將事務行為應用於方法

[英]Spring @Transactional doesn't apply transactional behavior to method

我試着用 Spring + JPA 弄臟我的手,我在行動第 4 版中閱讀了 Spring。 由於代碼示例不完整,我自己在 web 中尋找需要的代碼部分。但似乎我做錯了,因為當我調用 EntityManager.persist() 時它不起作用。 甚至沒有拋出異常

我的代碼如下

數據配置

@Configuration
@EnableTransactionManagement
public class DataConfig {

    @Bean
    public DataSource dataSource() {
        SingleConnectionDataSource ds = new SingleConnectionDataSource();
        ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/dbname");
        ds.setSuppressClose(true);
        ds.setUsername("user");
        ds.setPassword("password");
        return ds;
    }

    @Bean
    public JpaVendorAdapter jpaVendorAdapter(){
        HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
        adapter.setDatabase(Database.MYSQL);
        adapter.setShowSql(true);
        adapter.setGenerateDdl(false);
        adapter.setDatabasePlatform("org.hibernate.dialect.MySQLDialect");
        return adapter;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, JpaVendorAdapter jpaVendorAdapter){
        LocalContainerEntityManagerFactoryBean emfb = new LocalContainerEntityManagerFactoryBean();
        emfb.setDataSource(dataSource);
        emfb.setJpaVendorAdapter(jpaVendorAdapter);
        emfb.setPackagesToScan("spittr.domain");
        return emfb;
    }

    @Bean
    public PlatformTransactionManager transactionManager(DataSource ds){
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setDataSource(ds);
        return transactionManager;
    }
}

資料庫

@Repository
public class JpaSpittleRepository implements SpittleRepository{

    @PersistenceUnit
    private EntityManagerFactory emf;

    //other methods...

    @Transactional
    public void save(Spittle spittle) {
        EntityManager em = emf.createEntityManager();
        em.persist(spittle);
    }

}

所以在這個配置中 save() 什么都不保存。

當然,如果顯式地向該方法添加一對代碼行,例如:

@Transactional //unnecessary now
    public void save(Spittle spittle) {
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        em.persist(spittle);
        tx.commit();
    }

save() 工作正常(即使沒有@Transactional)

我還發現 @Transactional確實用 JpaTransactionManager 的 doBegin() 和 doCommit() 方法包裝了 save() 方法。

你會建議在哪里挖掘更多以找到問題?

同一本書提供了另一種配置 Repository 的方法,即用 EntityManager 替換 EntityManagerFactory 的注入:

    //@PersistenceUnit
    @PersistenceContext
    //private EntityManagerFactory emf;
    private EntityManager em;

如前所述,在每個方法中調用 emf.createEntityManager() 都會創建新的 EntityManager,這會使有關交易的事情變得復雜

現在它起作用了,盡管對我來說問題的根本原因仍然不清楚

暫無
暫無

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

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