簡體   English   中英

Spring(5.0.8)事務性和jdbcTemplate

[英]Spring (5.0.8) Transactional and jdbcTemplate

我想要一個經典的事務行為:創建a,創建b,如果創建b失敗,則回滾創建a。
“沒有那么困難,在您的方法上放置一個@Transactional spring注釋。”
我也是。但這是行不通的。
我正在使用spring mvc 5.0.8(在pom.xml下面的spring tx,上下文具有相同的版本號)。 該數據庫是mysql v.5.7.23
首先是我的配置/代碼,然后是一些很多的冗余錯誤。

這是服務級別的方法。

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public B createB(B b) {
    //some logic to create a, instance of A
    aDao.saveA(a);
    //some logic to create b, instance of B
    return bDao.saveB(b);
}

這是數據源,jdbctemplate和事務管理器配置:

@Bean
public DataSource dataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName(env.getRequiredProperty("jdbc.driverClassName"));
    dataSource.setUrl(env.getRequiredProperty("jdbc.url"));
    dataSource.setUsername(env.getRequiredProperty("jdbc.username"));
    dataSource.setPassword(env.getRequiredProperty("jdbc.password"));
    return dataSource;
}

@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
    jdbcTemplate.setResultsMapCaseInsensitive(true);
    return jdbcTemplate;
}

@Bean("transactionManager")
public PlatformTransactionManager getTransactionManager(DataSource dataSource) {
    DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
    dataSourceTransactionManager.setDataSource(dataSource);
    return dataSourceTransactionManager;
}

這是我pom.xml的一部分:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
</dependency>

如果您需要來自Daos或其他的更多代碼,請詢問。

編輯1:添加daos

@Repository
public class SqlADao implements ADao {
    private static final String CREATE_A = "INSERT INTO a(id, param1,  
    param2) VALUES(?, ?, ?)";

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public Addressee saveA(A a) {
        try {
            String id = UUID.randomUUID().toString();
            a.setId(id);
            jdbcTemplate.update(CREATE_A, id, a.getParam1(),  
                addressee.getParam2());
            return a;
        } catch (Exception e) {
            throw new DaoException("Exception while accessing data.", e);
        }

    }
}

@Repository
public class SqlBDao implements BDao {

    private static final String CREATE_B = "INSERT INTO b(id, param1,  
    param2, param3, param4, param5, param6) VALUES(?, ?, ?, ?, ?, ?, ?)";

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public Account saveAccount(Account account) {
        try {
            String id = UUID.randomUUID().toString();
            b.setId(id);
            jdbcTemplate.update(CREATE_B, id, b.getParam1(),  
                Date.valueOf(b.getParam2LocalDate()), b.getParam3,  
                b.getParam4(), b.getParam5(),b.getParam6());
            return b;
        } catch (Exception e) {
            throw new DaoException("Exception while accessing data.", e);
        }
    }
}

編輯結束1

現在,可能在互聯網上許多地方找到答案,主要是stackoverflow:

  • 回滾僅適用於未經檢查的異常(= RuntimeException)。
    BDao引發自定義RuntimeException。 我在@Transactionnal定義上添加了“ rollbackFor = Exception.class”。
  • 由於內部事務@Transactional起作用(AOP),因此必須從方法外部調用它。
    就是這種情況,“ createB”方法是從另一個類直接調用的(目前,僅從控制器調用)。
  • 您必須使用此精確名稱定義“ transactionManager”。
    一開始我沒有交易經理。 當我意識到時,我感到有點傻。 但是,即使只有一個名稱正確的名稱,也無法使用。
  • 我什至發現有人需要添加propagation = Propagation.REQUIRED,所以我也這樣做了,但是它並沒有改變任何東西。
  • 數據庫必須支持事務,回滾...
    這是一個在所有表上都帶有InnoDB引擎的mysql,根據相同的答案,它也支持它。

現在,我沒有其他想法,也無法在互聯網上找到其他想法,所以我在這里。

使用事務時,請確保已使用@Configuration上的@EnableTransactionManagement啟用了事務。

沒有該注釋,您基本上將沒有事務運行,這會使每個操作都在其自己的事務中運行。

暫無
暫無

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

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