原生jdbc使用spring事物

我们在使用 mybatis结合spring事物都是按照标准的模板进行处理,这让我们只是知其然而不知其所以然。这让我情何以堪,所以必须阅读源码并加上调试,搞懂其处理机制

在使用mybatis-spring时,mybatis-spring 官网的入门教程中有如下说明:

原生jdbc使用spring事物_第1张图片

只需要往spring容器中注入该bean就完成了mybatis与spring事物的关联。具体如何关联的,还是得阅读源码才能知晓。这个我们放到下次再说。

在阅读mybatis-spring的源码时我看到了

TransactionAwareDataSourceProxy.java 这个类,在网上搜了一下,并阅读spring的官方文档,大致是说,该类是普通数据源的代理类,可以让普通数据源感知到spring的事物上下文。刚开始并不是很理解这句话是什么意思。可以这样理解,如果我们想使用spring的事物,但不使用spring的jdbcTemplate,就使用的原生的jdbc代码,那么我们可以使用TransactionAwareDataSourceProxy将原生jdbc与spring事物关联起来。具体代码如下:
/**
 * 以上所有都是可以调用DataSourceUtils化简代码,而JdbcTemplate又是调用DataSourceUtils的。所以在 Spring文档中要求尽量首先使用JdbcTemplate,其次是用DataSourceUtils来获取和释放连接。至于 TransactionAwareDataSourceProxy,那是下策的下策。不过可以将Spring事务管理和遗留代码无缝集成。
 * 所以如某位朋友说要使用Spring的事务管理,但是又不想用JdbcTemplate,那么可以考虑TransactionAwareDataSourceProxy。这个类是原来DataSource的代理。
 * 其次,想使用Spring事物,又不想对Spring进行依赖是不可能的。与其试图自己模拟DataSourceUtils,不如直接使用现成的。
 *
 * 下面就是验证TransactionAwareDataSourceProxy的作用
 */
@Test
public void test5() {
    Connection connection = null;
    DataSourceTransactionManager dataSourceTransactionManager = null;
    TransactionStatus transaction = null;
    TransactionAwareDataSourceProxy transactionAwareDataSourceProxy = null;
    try {
        //创建数据源
        SimpleDriverDataSource simpleDriverDataSource = new SimpleDriverDataSource();
        simpleDriverDataSource.setDriverClass(com.mysql.jdbc.Driver.class);
        simpleDriverDataSource.setPassword("test1234");
        simpleDriverDataSource.setUsername("root");
        simpleDriverDataSource.setUrl("jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF8");

        //创建数据源代理
        transactionAwareDataSourceProxy = new TransactionAwareDataSourceProxy();
        transactionAwareDataSourceProxy.setTargetDataSource(simpleDriverDataSource);
        transactionAwareDataSourceProxy.afterPropertiesSet();

        //开启spring事物管理
        dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(transactionAwareDataSourceProxy);
        dataSourceTransactionManager.afterPropertiesSet();
        DefaultTransactionDefinition defaultTransactionDefinition = new DefaultTransactionDefinition();


        //开启事物并创建链接,并设置事物属性,将链接放到ThreadLocal中
        transaction = dataSourceTransactionManager.getTransaction(defaultTransactionDefinition);
        //通过spring的数据源代理,获取已经创建了的链接,将原生jdbc与spring事物关联起来
        connection = transactionAwareDataSourceProxy.getConnection();
        connection.setAutoCommit(false);
        PreparedStatement preparedStatement = connection.prepareStatement("update user set name = ? where id = ?");
        preparedStatement.setString(1, "test");
        preparedStatement.setInt(2, 2);
        preparedStatement.executeUpdate();
    } catch (Exception e) {
        try {
            dataSourceTransactionManager.rollback(transaction);
        } catch (Exception e1) {

        }
    } finally {
        try {
            /*
            事物提交会自动关闭链接,具体由DataSourceUtils.releaseConnection(this.connection, this.dataSource);这个方法关闭
            该方法广泛用于spring的jdbcTemplate(即spring jdbc中),mybatis-spring的SpringManagedTransaction,TransactionAwareDataSourceProxy,
            DataSourceTransactionManager
             */
            dataSourceTransactionManager.commit(transaction);
        } catch (Exception e2) {

        }
    }


}

 

如果我们不使用TransactionAwareDataSourceProxy.java 也想将原生jdbc与spring事物结合呢,如何处理。代码如下:

 

@Test
public void test6() {
    Connection connection = null;
    DataSourceTransactionManager dataSourceTransactionManager = null;
    TransactionStatus transaction = null;
    TransactionAwareDataSourceProxy transactionAwareDataSourceProxy = null;
    try {
        //创建数据源
        SimpleDriverDataSource simpleDriverDataSource = new SimpleDriverDataSource();
        simpleDriverDataSource.setDriverClass(com.mysql.jdbc.Driver.class);
        simpleDriverDataSource.setPassword("test1234");
        simpleDriverDataSource.setUsername("root");
        simpleDriverDataSource.setUrl("jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF8");

        //开启spring事物管理
        dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(simpleDriverDataSource);
        dataSourceTransactionManager.afterPropertiesSet();
        DefaultTransactionDefinition defaultTransactionDefinition = new DefaultTransactionDefinition();


        //开启事物并创建链接,并设置事物属性,将链接放到ThreadLocal中
        transaction = dataSourceTransactionManager.getTransaction(defaultTransactionDefinition);
        //直接通过DataSourceUtils获取已经创建了的链接
        connection = DataSourceUtils.getConnection(simpleDriverDataSource);
        connection = transactionAwareDataSourceProxy.getConnection();
        connection.setAutoCommit(false);
        PreparedStatement preparedStatement = connection.prepareStatement("update user set name = ? where id = ?");
        preparedStatement.setString(1, "test");
        preparedStatement.setInt(2, 2);
        preparedStatement.executeUpdate();
    } catch (Exception e) {
        try {
            dataSourceTransactionManager.rollback(transaction);
        } catch (Exception e1) {

        }
    } finally {
        try {
            /*
            事物提交会自动关闭链接,具体由DataSourceUtils.releaseConnection(this.connection, this.dataSource);这个方法关闭
            该方法广泛用于spring的jdbcTemplate(即spring jdbc中),mybatis-spring的SpringManagedTransaction,TransactionAwareDataSourceProxy,
            DataSourceTransactionManager
             */
            dataSourceTransactionManager.commit(transaction);
        } catch (Exception e2) {

        }
    }


}

mybatis-spring就是使用的方式二将mybatis与spring事物进行关联的

 

你可能感兴趣的:(mybatis源码学习)