零xml配置Spring事务管理

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/dgeek/article/details/69456163

由于受Spring4实战这本书的影响,加上对xml没什么好感,窃以为基于Java的配置比基于xml的配置更方便,所以能不用xml配置文件我就尽可能不用。但由于Spring4实战里并没有讲有关事务管理这方面的内容,而网上的教程99.99999%都是使用了xml来配置的,但由于个人更倾向于完全基于Java的配置,所以只能自己想办法解决。
在xml配置中通常用这句来开启事务注解驱动

<!-- 事务注解驱动,标注@Transactional的类和方法将具有事务性 -->  
<tx:annotation-driven transaction-manager="txManager" />  

但有没有方法可以代替这句话,我找了很久,终于发现在知乎中也有相关问题tx:annotation-driven用什么注解代替

在查阅了Spring官方文档之后,我找到了答案。

在官方文档里

It is not sufficient to tell you simply to annotate your classes with the @Transactional annotation, add @EnableTransactionManagement to your configuration, and then expect you to understand how it all works. This section explains the inner workings of the Spring Framework’s declarative transaction infrastructure in the event of transaction-related issues.
The most important concepts to grasp with regard to the Spring Framework’s declarative transaction support are that this support is enabled via AOP proxies, and that the transactional advice is driven by metadata (currently XML- or annotation-based). The combination of AOP with transactional metadata yields an AOP proxy that uses a TransactionInterceptor in conjunction with an appropriate PlatformTransactionManager implementation to drive transactions around method invocations.

也就是说,除了要用@Transactional注解之外,还要用@EnableTransactionManagement来 启用注解式事务管理,其效果等同于上面的xml配置中的< tx:annotation-driven/>,但此时还不能起效果,因为
还要找个东西来代替transaction-manager属性,官方文档也给出了解决方法,就是让配置类实现TransactionManagementConfigurer接口,它会覆盖一个方法,(return那句是我自己加的)

@Override
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }

贴上官方示例

@Configuration
 @EnableTransactionManagement
 public class AppConfig implements TransactionManagementConfigurer {

     @Bean
     public FooRepository fooRepository() {
         // configure and return a class having @Transactional methods
         return new JdbcFooRepository(dataSource());
     }

     @Bean
     public DataSource dataSource() {
         // configure and return the necessary JDBC DataSource
     }

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

     @Override
     public PlatformTransactionManager annotationDrivenTransactionManager() {
         return txManager();
     }
 }

最后贴上我根据看慕课网视频修改的零xml配置的代码

@EnableTransactionManagement
@Configuration
@ComponentScan
public class Config implements TransactionManagementConfigurer{
    private static final String DRIVER;
    private static final String URL;
    private static final String USERNAME;
    private static final String PASSWORD;
    private static final String FILEPATH="src/main/java/transaction/db.properties";

    static {
        Properties properties=new Properties();
        try {
            InputStream in=new FileInputStream(new File(FILEPATH));
            properties.load(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
        DRIVER=properties.getProperty("driver");
        URL=properties.getProperty("url");
        USERNAME=properties.getProperty("user");
        PASSWORD=properties.getProperty("password");
    }

    //配置C3P0数据源连接池
    @Bean
    public ComboPooledDataSource dataSource(){
        ComboPooledDataSource dataSource=new ComboPooledDataSource();
        try {
            dataSource.setDriverClass(DRIVER);
            dataSource.setJdbcUrl(URL);
            dataSource.setUser(USERNAME);
            dataSource.setPassword(PASSWORD);
            dataSource.setInitialPoolSize(5);
        } catch (PropertyVetoException e) {
            e.printStackTrace();
        }
        return dataSource;
    }

    @Bean
    public JdbcTemplate jdbcTemplate(){
        return new JdbcTemplate(dataSource());
    }


    @Bean
    @Override
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }
}
@Service
public class AccountServiceImpl implements AccountService{

    private AccountDao accountDao;

    @Transactional
    @Override
    public void transfer(String out, String in, double money) {
        accountDao.outMoney(out,money);
        int i=1/0; //抛出一个异常
        accountDao.inMoney(in, money);
    }

    @Autowired
    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

}
@Repository
public class AccountDaoImpl implements AccountDao{

    private JdbcTemplate template;

    @Autowired
    public AccountDaoImpl(JdbcTemplate template) {
        this.template=template;
    }


    @Override
    public void outMoney(String out, double money) {
        String sql="update account set money = money - ? where name = ?";
        template.update(sql,money,out);

    }

    @Override
    public void inMoney(String in, double money) {
        String sql="update account set money = money + ? where name = ?";
        template.update(sql,money,in);
    }
}

总结:官方文档才是最好的教程

展开阅读全文

没有更多推荐了,返回首页