Spring 学习笔记之事务管理

Spring 学习笔记之事务管理

Module 介绍

Spring-Transaction-Annotaion:以注解方式配置的声明式事务

Spring-Transaction-XML:以XML方式配置的声明式事务

Spring 事务控制

事务控制分类

  • 编程式事务(略)

  • 声明式事务

    • 以XML方式配置的声明式事务
    • 以注解方式配置的声明式事务

以XML方式配置的声明式事务

pom.xml需要引入:

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-aopartifactId>
dependency>
<dependency>
    <groupId>org.aspectjgroupId>
    <artifactId>aspectjrtartifactId>
dependency>
<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-jdbcartifactId>
dependency>

Springboot 引入 事务控制配置文件(applicationContext-db.xml)

ApplicationContextConfig.java

package top.simba1949;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author [email protected]
 * @date 2018/8/25 8:01
 */
@SpringBootApplication
@MapperScan(basePackages = "top.simba1949.mapper")
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
    }
}

applicationContext.xml 和 applicationContext-db.xml融合到一个spring容器中

applicationContext.xml


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <import resource="applicationContext-db.xml">import>
beans>

applicationContext-db.xml


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       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.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:property-placeholder location="jdbc.properties"/>

    <aop:config>
        <aop:pointcut id="aopPoincut" expression="execution(* top.simba1949.service.impl.*.*(..))">aop:pointcut>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="aopPoincut">aop:advisor>
    aop:config>
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            
            <tx:method name="add*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception"/>
            <tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception"/>
            <tx:method name="insert*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception"/>
            <tx:method name="update*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception"/>
            <tx:method name="modify*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception"/>
            <tx:method name="delete*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception"/>

            <tx:method name="query*" read-only="true">tx:method>
            <tx:method name="select*" read-only="true">tx:method>
            <tx:method name="find*" read-only="true">tx:method>
        tx:attributes>
    tx:advice>
    
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource">property>
    bean>
    
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}">property>
        <property name="url" value="${jdbc.url}">property>
        <property name="username" value="${jdbc.username}">property>
        <property name="password" value="${jdbc.password}">property>
    bean>

    
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        
        <property name="dataSource" ref="dataSource">property>
        
        <property name="configLocation" value="classpath:mybatis-config.xml">property>
        
        <property name="mapperLocations">
            <array>
                <value>classpath*:top/simba1949/mapper/*Mapper.xmlvalue>
            array>
        property>
        
        <property name="typeAliasesPackage" value="top.simba1949.common">property>
    bean>
    
    <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        
        <property name="basePackage" value="top.simba1949.mapper">property>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory">property>
    bean>
beans>

mybatis-config.xml




<configuration>

configuration>

jdbc.properties

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=19491001

以注解方式配置的声明式事务

application.properteis

server.port=8083

#mysql设置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=19491001

#表示打印出sql语句
logging.level.com.shyroke.mapper=debug

#mybatis配置
mybatis.mapper-locations=classpath*:top/simba1949/mapper/*Mapper.xml
mybatis.type-aliases-package=top.simba1949.common

Application.java

package top.simba1949;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author [email protected]
 * @date 2018/8/25 8:01
 * @MapperScan(basePackages = "top.simba1949.mapper")扫描mapper包
 */
@SpringBootApplication
@MapperScan(basePackages = "top.simba1949.mapper")
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
    }
}

CountryServiceImpl.java

@Transactional(rollbackFor = Exception.class)即可开启注解

package top.simba1949.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.simba1949.common.CountryCommon;
import top.simba1949.mapper.CountryMapper;
import top.simba1949.service.CountryService;

/**
 * @author [email protected]
 * @date 2018/8/24 23:22
 */
@Service
public class CountryServiceImpl implements CountryService {

    @Autowired
    private CountryMapper countryMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insert(CountryCommon countryCommon) {
        int i = countryMapper.insert(countryCommon);
        return i;
    }
}

@Transactional 注解详解

@Transactional(
    propagation = Propagation.REQUIRED,
    isolation = Isolation.DEFAULT,
    timeout = -1,
    readOnly = false,
    rollbackFor = Exception.class,
    noRollbackFor = Exception.class
)
属性 含义 默认值
propagation,定义事务的生命周期 REQUIRED:方法A调用式没有事务新建一个事务,当方法A调用另一个方法B时,方法B将使用相同的事务;如果方法B发生异常需要回滚的时候,整个事务数据回滚 REQUIRED
REQUIRED_NEW:方法A和方法B,在方法调用的时候无论是否有事务都开启一个新事务;这样如果方法B有异常不会导致方法A的数据回滚
NESTED:和REQUIRED_NEW类似,但是支持JDBC,不支持JPA和Hibernate
NOT_SUPPORTED:强制方法不在事务中执行,若有事务,在方法调用结束阶段事务将被挂起
NEVER:强制方法不在事务中执行,若有事务则抛出异常
MANDATORY:强制方法在事务中执行,若无事务则抛出异常
isolation:(隔离)决定了事务的完整性,处理在多事务对相同数据的处理机制 READ_UNCOMMITTED:对于在A事务里修改了一条记录但是没有提交事务,在B事务可以读取到修改后的记录。可导致脏读,可不重复读以及幻读 DEFAULT(使用当前数据库默认的级别,oracle、sql server默认为READ_COMMITTED,mysql默认REPEATABLE_READ)
READ_COMMITTED:只有当事务A里修改了一条记录且提交事务之后,B事务才可以读取到提交后的记录;阻止脏读,但是可导致不可重复读和幻读
REPEATABLE_READ:不仅能实现READ_COMMITTED的功能,而且还能阻止当A事务读取了一条记录,B事务将不允许修改这条记录;阻止了脏读,不可重复读,但是可导致幻读
SERIALIZABLE:此级别下事务是顺序执行的,可以避免上述级别的缺陷,但是开销比较大
timeout timeout事务过期时间,默认为当前数据库的事务过期时间
readonly 指定当前事务是否是只读事务 false
rollbackfor 指定哪个或者哪些异常可以引起事务回滚 Throwable的子类
noRollbackfor 指定哪个或者哪些异常不可以引起事务回滚 Throwable的子类

你可能感兴趣的:(Spring)