技术栈

六、(二)使用注解定义事务

2019-07-23  本文已影响0人  烟雨乱平生

<tx:advice>配置元素极大的简化了Spring声明式事务所需要的XML。除了<tx:advice>元素,tx命名空间还提供了<tx:annotation-driven>元素。使用<tx:annotation-driven>时,通常只需要一行XML:<tx:annotation-driven />.

当然,我们也可以通过transaction-manager属性来指定特定的事务管理器。

<tx:annotation-driven />元素告诉Spring检查上下文中所有的Bean并查找使用@Transaction注解的Bean,而不管这个注解是用在类级别上还是方法级别上。对于每一个使用@Transaction注解的Bean,<tx:annotation-driven />会自动为它添加事务通知。通知的事务属性是通过@Transaction注解的参数来定义的。

相比较于<tx:annotation-driven />元素仍然是XML配置,Spring提供了等价的@EnableTransactionManagement注解。

启用注解

@Configuration
@EnableTransactionManagement
public class DataSourceConfig {
  
}

定义事务管理器

@Configuration
@EnableTransactionManagement
public class DataSourceConfig {

    @Bean(name = "dataSource")
    public DataSource dataSource(){
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/userinfo?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false");
        dataSource.setUsername("root");
        dataSource.setPassword("");
        return dataSource;
    }

    @Bean(name = "dbcp")
    public DataSource dbcp(){
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/userinfo?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false");
        dataSource.setUsername("root");
        dataSource.setPassword("");
        dataSource.setInitialSize(5);
        dataSource.setMaxIdle(10);
        return dataSource;
    }

    @Bean(name = "c3p0")
    public DataSource c3p0() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass("com.mysql.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/userinfo?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false");
        dataSource.setUser("root");
        dataSource.setPassword("");
        dataSource.setInitialPoolSize(5);
        dataSource.setMaxPoolSize(10);
        return dataSource;
    }

    @Bean(name = "druid")
    public DataSource druid() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/userinfo?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false");
        dataSource.setUsername("root");
        dataSource.setPassword("");
        dataSource.setInitialSize(5);
        dataSource.setMaxActive(10);
        return dataSource;
    }

    @Bean
    public PlatformTransactionManager transactionManager(){
        PlatformTransactionManager transactionManager = new DataSourceTransactionManager(dataSource());
        return transactionManager;
    }

}

事务管理器需要指定数据源

使用事务

@Component
public class UserServiceUseTemplate {

    @Autowired
    private JdbcTemplate template;

    @Autowired
    private NamedParameterJdbcTemplate namedTemplate;

    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = RollbackException.class)
    public void insert(User user){
        String sql = "insert into user(name,account,password,gender) values(:name,:account,:password,:gender)";
        Map<String,Object> params = new HashMap<>();
        params.put("name",user.getName());
        params.put("account",user.getAccount());
        params.put("password",user.getPassword());
        params.put("gender",user.getGender());
        namedTemplate.update(sql,params);
        throw new RollbackException("需要回滚");
    }
}

在本例中,模板类NamedParameterJdbcTemplateJdbcTemplate和事务管理器PlatformTransactionManager都需要指定数据源,所以如果模板类和事务管理器使用相同的数据源,那么事务是有效的,否则事务不生效。

上一篇 下一篇

猜你喜欢

热点阅读