spring 配置事務管理器

  在Spring中數據庫事務是經過PlatformTransactionManager進行管理的,jdbcTemplate是不能支持事務的,而可以支持事務的是org.springframework.transaction.support.TransactionTemplate模板,它是Spring所提供的事務管理器的模板
  •事務的建立、提交和回滾是經過PlatformTransactionManager接口來完成的。
  •當事務產生異常時會回滾事務,在默認的實現中全部的異常都會回滾。咱們能夠經過配置去修改在某些異常發生時回滾或者不回滾事務。
  •當無異常時,會提交事務。java

  支持JTA事務,經常使用的是DataSourceTransactionManager,它繼承抽象事務管理器AbstractPlatformTransactionManager,而AbstractPlatformTransactionManager又實現了PlatformTransactionManager。這樣Spring就能夠如同源碼中看到的那樣使用PlatformTransactionManager接口的方法,建立、提交或者回滾事務了。mysql

配置事務管理器

  MyBatis框架用得最多的事務管理器是DataSourceTransactionManager(org.springframework.jdbc.datasource.DataSourceTransactionManager),所以下面將以此例進行講解。若是使用的持久框架是Hibernate,那麼你就要用到spring-orm包org.springframework.orm.hibernate4.HibernateTransactionManager了。它們大同小異,通常而言咱們在使用時,還會加入XML的事務命名空間。下面配置一個事務管理器spring

<?xml version='1.0' encoding='UTF-8' ?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
      http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <!-- 數據庫鏈接池 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/springmvc?useSSL=false&amp;serverTimezone=Hongkong&amp;characterEncoding=utf-8&amp;autoReconnect=true"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
        <property name="maxActive" value="255"/>
        <property name="maxIdle" value="5"/>
        <property name="maxWait" value="10000"/>
    </bean>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 配置數據源事務管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

</beans>

 

  這裏先引入了XML的命名空間,而後定義了數據庫鏈接池,因而使用了DataSourceTransactionManager去定義數據庫事務管理器,而且注入了數據庫鏈接池。這樣Spring就知道你已經將數據庫事務委託給事務管理器transactionManager管理了。在jdbcTemplate源碼分析時,筆者就已經指出,數據庫資源的產生和釋放若是沒有委託給數據庫管理器,那麼就由jdbcTemplate管理,可是此時已經委託給了事務管理器,因此jdbcTemplate的數據庫資源和事務已經由事務管理器處理了。sql

  在Spring中可使用聲明式事務或者編程式事務,現在編程式事務幾乎不用了,由於它會產生冗餘,代碼可讀性較差。聲明式事務又能夠分爲XML配置和註解事務,但XML方式也已經不經常使用了,目前主流方法是註解@Transactional。數據庫

用Java配置方式實現Spring數據庫事務

  用Java配置的方式來實現Spring數據庫事務,須要在配置類中實現接口TransactionManagementConfigurer的annota-tionDrivenTransactionManager方法。Spring會把annotationDrivenTransactionManager方法返回的事務管理器做爲程序中的事務管理器
  代碼清單:使用Java配置方式實現Spring數據庫事物apache

package com.ssm.chapter13.config;

import org.apache.commons.dbcp.BasicDataSourceFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;

import javax.sql.DataSource;
import java.util.Properties;

@Configuration
@ComponentScan("com.ssm.chapter13.*")
//使用事務驅動管理器
@EnableTransactionManagement
public class JavaConfig implements TransactionManagementConfigurer {

    //數據源
    private DataSource dataSource = null;

    /**
     * 配置數據源.   * @return 數據源.
     */
    @Bean(name = "dataSource")
    public DataSource initDataSource() {
        if (dataSource != null) {
            return dataSource;
        }
        Properties props = new Properties();
        props.setProperty("driverClassName", "com.mysql.cj.jdbc.Driver");
        props.setProperty("url", "jdbc:mysql://localhost:3306/springmvc?useSSL=false&serverTimezone=Hongkong&characterEncoding=utf-8&autoReconnect=true");
        props.setProperty("username", "root");
        props.setProperty("password", "123456");
        props.setProperty("maxActive", "200");
        props.setProperty("maxIdle", "20");
        props.setProperty("maxWait", "30000");
        try {
            dataSource = BasicDataSourceFactory.createDataSource(props);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dataSource;
    }

    /**
     * 配置jdbcTemplate   * @return jdbcTemplate
     */
    @Bean(name = "jdbcTemplate")
    public JdbcTemplate initjdbcTemplate() {
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(initDataSource());
        return jdbcTemplate;
    }

    /**
     * 實現接口方法,使得返回數據庫事務管理器
     */
    @Override
    @Bean(name = "transactionManager")
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        //設置事務管理器管理的數據源
        transactionManager.setDataSource(initDataSource());
        return transactionManager;
    }
}

 

  實現了TransactionManagementConfigurer接口所定義的方法annotation DrivenTransactionManager,而且咱們使用DataSourceTransactionManager去定義數據庫事務管理器的實例,而後把數據源設置給它。注意,使用註解@EnableTransactionManagement後,在Spring上下文中使用事務註解@Transactional,Spring就會知道使用這個數據庫事務管理器管理事務了。編程

編程式事務

  編程式事務以代碼的方式管理事務,換句話說,事務將由開發者經過本身的代碼來實現,這裏須要使用一個事務定義類接口——TransactionDefinition,暫時不進行深刻的介紹,咱們只要使用默認的實現類——DefaultTransactionDefinition就能夠了。
  代碼清單:編程式事務mvc

package com.ssm.chapter13.main;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

public class MainTest {

    public static void main(String[] args) {

        ApplicationContext ctx = new ClassPathXmlApplicationContext("ssm/chapter13/spring-cfg.xml");//ctx爲Spring IoC容器

        JdbcTemplate jdbcTemplate = ctx.getBean(JdbcTemplate.class);
        //事務定義類
        TransactionDefinition def = new DefaultTransactionDefinition();
        PlatformTransactionManager transactionManager = ctx.getBean(PlatformTransactionManager.class);
        TransactionStatus status = transactionManager.getTransaction(def);
        try {
            //執行SQL語句
            jdbcTemplate.update("insert into t_role(role_name, note) " + "values('role_name_transactionManager', 'note_transactionManager')");
            //提交事務
            transactionManager.commit(status);
        } catch (Exception ex) {
            //回滾事務
            transactionManager.rollback(status);
        }

    }


}

 

  從代碼中能夠看到全部的事務都是由開發者本身進行控制的,因爲事務已交由事務管理器管理,因此jdbcTemplate自己的數據庫資源已經由事務管理器管理,所以當它執行完insert語句時不會自動提交事務,這個時候須要使用事務管理器的commit方法,回滾事務須要使用rollback方法。
固然這是最簡單的使用方式,由於這個方式已經不是主流方式,甚至幾乎是不被推薦使用的方式,之因此介紹是由於它的代碼流程更爲清晰,有助於將來對編程式事務的理解。框架

  編程式事務是一種約定型的事務,在大部分狀況下,當使用數據庫事務時,大部分的場景是在代碼中發生了異常時,須要回滾事務,而不發生異常時則是提交事務,從而保證數據庫數據的一致性。ide

相關文章
相關標籤/搜索