其他分享
首页 > 其他分享> > Spring 16: SM(Spring + MyBatis) 注解式事务 与 声明式事务

Spring 16: SM(Spring + MyBatis) 注解式事务 与 声明式事务

作者:互联网

Spring事务处理方式

方式1:注解式事务

方式2:声明式事务

声明式事务案例

applicationContext_trans.xml

<!-- 此配置文件和applicationContext_service.xml的功能一样,只不过是事务配置不同 -->

<?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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">

        <!-- 导入applicationContext_mapper.xml -->
        <import resource="applicationContext_mapper.xml"/>

        <!-- 添加包扫描 -->
        <context:component-scan base-package="com.example.service.impl"/>

        <!-- 添加事务管理器 -->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"/>
        </bean>

        <!-- 配置事务切面 -->
        <tx:advice id="myadvice" transaction-manager="transactionManager">
            <tx:attributes>
                <tx:method name="*select*" read-only="true"/>
                <tx:method name="*search*" read-only="true"/>
                <tx:method name="*find*" read-only="true"/>
                <tx:method name="*get*" read-only="true"/>
                <tx:method name="*update*" propagation="REQUIRED"/>
                <tx:method name="*save*" propagation="REQUIRED"/>
                <tx:method name="*modify*" propagation="REQUIRED"/>
                <tx:method name="*set*" propagation="REQUIRED"/>
                <tx:method name="*insert*" propagation="REQUIRED"/>
                <tx:method name="*delete*" propagation="REQUIRED"/>
                <tx:method name="*remove*" propagation="REQUIRED"/>
                <tx:method name="*clear*" propagation="REQUIRED"/>
                <tx:method name="*" propagation="SUPPORTS"/>
            </tx:attributes>
        </tx:advice>

        <!-- 绑定切面和切入点 -->
        <aop:config>
            <!-- 定义切入点表达式 -->
            <aop:pointcut id="mycut" expression="execution(* com.example.service.impl.*.*(..))"/>

            <!-- 将切面和切入点表达式绑定,为目标业务实现类中的业务方法提供对应的事务切面功能 -->
            <aop:advisor advice-ref="myadvice" pointcut-ref="mycut"/>
        </aop:config>
</beans>

业务实现类

package com.example.service.impl;


import com.example.mapper.UserMapper;
import com.example.pojo.Account;
import com.example.pojo.User;
import com.example.service.AccountService;
import com.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 业务实现类
 */
@Service
public class UserServiceImpl implements UserService {
    //业务逻辑层实现类持有数据访问层的接口类型的变量
    @Autowired
    UserMapper userMapper;

    //持有Account业务逻辑层的接口类型的变量
    @Autowired
    AccountService accountService;

    @Override
    public int insert(User user) {
        int num = userMapper.insert(user);
        if(num == 1){
            System.out.println("用户导入成功!");
        }else{
            System.out.println("用户导入失败!");
        }
        
        //嵌套调用账户的业务逻辑功能
        accountService.save(new Account(25, "荷包蛋6","富婆的账户6"));
        return num;
    }
}

测试

package com.example.test;

import com.example.pojo.User;
import com.example.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestUserAndAccount {
    @Test
    public void testUserAndAccount(){
        //创建Spring容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext_trans.xml");
        //获取用户的业务逻辑层对象
        UserService userService = (UserService) ac.getBean("userServiceImpl");
        //调用业务功能
        userService.insert(new User(2, "荷包蛋2", "hanzhanghan2"));
    }
}

测试输出

image

image

修改aplicationContext_trans.xml

<tx:method name="*save*" propagation="REQUIRED" no-rollback-for="ArithmeticException"/>
<tx:method name="*insert*" propagation="REQUIRED" no-rollback-for="ArithmeticException"/>

测试输出

image

注意

如果当声明式注解所规划的事务管理和某个业务层的业务方法对事务的个性化需求相冲突时,可以再另外开启注解式事务并设置两种事务的优先级,达到优先使用注解式事务的目的。当order属性的值越大,事务的优先级越高

        <!-- 添加注解式事务驱动-->
        <tx:annotation-driven order="10" transaction-manager="transactionManager"/>
 <aop:advisor order="1" advice-ref="myadvice" pointcut-ref="mycut"/>

Spring事务的传播特性

image

Spring事务的隔离原则

添加事务管理器的原因

    <!-- 添加事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 由于事务管理必然要涉及到数据库的操作,例如数据回滚等等,所以必须添加数据源配置 -->
        <property name="dataSource" ref="dataSource"/>
    </bean>

标签:事务,16,Spring,业务,import,注解,com,example
来源: https://www.cnblogs.com/nefu-wangxun/p/16636947.html