Spring事务配置

1 Spring 事务配置之xml与注解结合版

1.1 pom.xml坐标

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.12</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.1.9.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.4</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.2</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.20</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>2.0.1</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.1.9.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>5.1.9.RELEASE</version>
    </dependency>
</dependencies>

1.2 pojo类

package cn.bwm.pojo;

import lombok.Data;

/**
 * 账户实体类
 * @author bwm
 */
@Data
public class Account {
    private Integer id;
    private String name;
    private Double money;
}

1.3 Dao层接口

package cn.bwm.dao;

import cn.bwm.pojo.Account;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

/**
 * @author bwm
 */
public interface AccountDao {
    /**
     * 根据name查询账户
     *
     * @param name
     * @return
     */
    @Select("select * from account where name=#{name}")
    Account findAccountByName(String name);

    /**
     * 更新账户
     *
     * @param account
     */
    @Update("update account set name=#{name},money=#{money} where id=#{id} ")
    void updateAccount(Account account);
}

1.4 数据源配置文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis01?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=root

1.5 ★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: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/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">


    <!--配置数据源-->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!--配置连接池-->
    <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!--SqlSessionFactoryBean-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--关联数据源-->
        <property name="dataSource" ref="druidDataSource"/>
        <!--给pojo类起别名-->
        <property name="typeAliasesPackage" value="cn.bwm.pojo"/>
    </bean>

    <!--MapperScan..扫描mybatis生成的dao层接口-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="cn.bwm.dao"/>
    </bean>

    <!--开启Spring IOC注解扫描-->
    <context:component-scan base-package="cn.bwm"/>

    <!--通知spring识别AOP相关注解-->
<!--    <aop:aspectj-autoproxy/>-->

    <!--AOP事务-->
    <!--配置事务切面通知-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--关联数据源-->
        <property name="dataSource" ref="druidDataSource"/>
    </bean>

    <!--开启Spring 事务注解扫描-->
    <tx:annotation-driven/>

</beans>





1.6 业务层接口

package cn.bwm.service;

import cn.bwm.pojo.Account;

/**
 * 业务层接口
 * @author bwm
 */
public interface AccountService {
    /**
     * 根据name查询账户
     *
     * @param name
     * @return
     */
    Account findAccountByName(String name);

    /**
     * 更新账户
     *
     * @param account
     */
    void updateAccount(Account account);

    /**
     * 转账
     *
     * @param out   转出账户
     * @param in    转入账户
     * @param money 转账金额
     */
    void transfer(String out,String in,Double money);
}

1.7 业务层实现类

package cn.bwm.service.impl;

import cn.bwm.dao.AccountDao;
import cn.bwm.pojo.Account;
import cn.bwm.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author bwm
 */
@Service("accountService")
@Transactional(rollbackFor = Exception.class)
public class AccountServiceImpl implements AccountService {
    /*
        @Transactional 注解管理事务
        rollback-for 用于指定能够触发事务回滚的异常类型,如果有多个异常类型需要指定,各类型之间可以通过逗号分隔。
     */


    /**
     * 引入dao层
     */
    @Autowired
    @Qualifier("accountDao")
    private AccountDao accountDao;

    @Override
    public Account findAccountByName(String name) {
        return accountDao.findAccountByName(name);
    }

    @Override
    public void updateAccount(Account account) {
        accountDao.updateAccount(account);
    }

    @Override
   // @Transactional(rollbackFor = Exception.class)
    public void transfer(String out, String in, Double money) {
        //转出账户信息
        Account outAccount = accountDao.findAccountByName(out);
        System.out.println("转账前"+out+"的账户金额为:"+outAccount.getMoney());
        //转入账户信息
        Account inAccount = accountDao.findAccountByName(in);
        System.out.println("转账前"+in+"的账户金额为:"+inAccount.getMoney());
        //转账 入账操作
        outAccount.setMoney(outAccount.getMoney()-money);
        inAccount.setMoney(inAccount.getMoney()+money);
        //更新双方账户信息
        accountDao.updateAccount(outAccount);
        System.out.println("转账后"+out+"的账户金额为:"+outAccount.getMoney());
        //制造异常
        int i = 1 / 0 ;
        accountDao.updateAccount(inAccount);
        System.out.println("转账后"+in+"的账户金额为:"+inAccount.getMoney());
    }
}

1.8 业务层测试

package cn.bwm.service;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * @author bwm
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations ={"classpath:applicationContext.xml"})
public class AccountServiceTest {

    @Autowired
    @Qualifier("accountService")
    private AccountService accountService;

    @Test
    public void findAccountByName() {
        System.out.println(accountService.findAccountByName("李四"));
        System.out.println(accountService.findAccountByName("张三"));
    }

    @Test
    public void transfer() {
        accountService.transfer("李四","张三",10.0);
    }
}

项目结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tVckI4cq-1591623123242)(C:\Users\40425\Desktop\daydayup\assets\1591537628275.png)]

2 Spring 事务配置之纯注解版

2.1 pom.xml坐标

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.12</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.1.9.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.4</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.2</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.20</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>2.0.1</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.1.9.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>5.1.9.RELEASE</version>
    </dependency>
</dependencies>

2.2 pojo类

package cn.bwm.pojo;

import lombok.Data;

/**
 * 账户实体类
 * @author bwm
 */
@Data
public class Account {
    private Integer id;
    private String name;
    private Double money;
}

2.3 Dao层接口

package cn.bwm.dao;

import cn.bwm.pojo.Account;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

/**
 * @author bwm
 */
public interface AccountDao {
    /**
     * 根据name查询账户
     *
     * @param name
     * @return
     */
    @Select("select * from account where name=#{name}")
    Account findAccountByName(String name);

    /**
     * 更新账户
     *
     * @param account
     */
    @Update("update account set name=#{name},money=#{money} where id=#{id} ")
    void updateAccount(Account account);
}

2.4 数据源配置文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis01?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=root

2.5 ★config配置类

2.5.1 JdbcConfig

package cn.bwm.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import javax.sql.DataSource;
import java.sql.Connection;

/**
 * 数据源相关配置文件
 * @author bwm
 */

@PropertySource({"classpath:jdbc.properties"})
public class JdbcConfig {

    @Value("${jdbc.driver}")
    private String driver;

    @Value("${jdbc.url}")
    private String url;

    @Value("${jdbc.username}")
    private String username;

    @Value("${jdbc.password}")
    private String password;

    /**
     * 配置数据源连接池
     *
     * @return
     */
    @Bean("druidDataSource")
    public DataSource createDruidDataSource(){
        DruidDataSource ds = new DruidDataSource();
        //配置驱动,url,用户名,密码
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(username);
        ds.setPassword(password);
        return ds;
    }

    /**
     * 配置连接对象
     *
     * @param ds
     * @return
     */
    @Bean("connection")
    public Connection getConnection(@Qualifier("druidDataSource") DataSource ds){
        //开启 事务Connection对象与 MybatisConnection对象同步
        TransactionSynchronizationManager.initSynchronization();
        //获取Connection对象
        return DataSourceUtils.getConnection(ds);
    }
}

2.5.2 MybatisConfig

package cn.bwm.config;


import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;

import javax.sql.DataSource;

/**
 * MyBatis相关配置文件
 *
 * @author bwm
 */

public class MybatisConfig {

    /**
     * 配置 SqlSessionFactoryBean
     *
     * @param ds
     * @return
     */
    @Bean("sqlSessionFactory")
    public SqlSessionFactoryBean createSqlSessionFactoryBean(DataSource ds){
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        //关联数据源
        sqlSessionFactoryBean.setDataSource(ds);
        //给pojo类起别名
        sqlSessionFactoryBean.setTypeAliasesPackage("cn.bwm.pojo");
        return sqlSessionFactoryBean;
    }

    /**
     * 配置 MapperScannerConfigurer
     *
     * @return
     */
    @Bean
    public MapperScannerConfigurer createMapperScannerConfigurer(){
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        //扫描dao层接口
        mapperScannerConfigurer.setBasePackage("cn.bwm.dao");
        return mapperScannerConfigurer;
    }
}

2.5.3 TransactionManagerConfig

package cn.bwm.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

/**
 * spring 事务管理配置文件
 * @author bwm
 */

public class TransactionManagerConfig {
    /**
     * 创建Spring事务管理对象
     */
    @Bean("transactionManager")
    public DataSourceTransactionManager createDataSourceTransactionManager(DataSource ds){
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(ds);
        return dataSourceTransactionManager;
    }
}

2.5.4 SpringConfig

package cn.bwm.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.Import;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
 * 主配置文件
 * @author bwm
 */
@Configuration
@Import({JdbcConfig.class,MybatisConfig.class,TransactionManagerConfig.class})
@ComponentScan("cn.bwm")
@EnableAspectJAutoProxy
@EnableTransactionManagement
public class SpringConfig {
    /*
        注解说明:
           @Configuration 说明此类是配置类
           @Import  引入子配置文件
           @ComponentScan("cn.bwm") 开启IOC容器的注解扫描
           @EnableAspectJAutoProxy  开启AOP的注解扫描
           @EnableTransactionManagement 开启事务的注解扫描

    */
}

2.6 业务层接口

package cn.bwm.service;

import cn.bwm.pojo.Account;

/**
 * 业务层接口
 * @author bwm
 */
public interface AccountService {
    /**
     * 根据name查询账户
     *
     * @param name
     * @return
     */
    Account findAccountByName(String name);

    /**
     * 更新账户
     *
     * @param account
     */
    void updateAccount(Account account);

    /**
     * 转账
     *
     * @param out   转出账户
     * @param in    转入账户
     * @param money 转账金额
     */
    void transfer(String out,String in,Double money);
}

2.7 业务层实现类

package cn.bwm.service.impl;

import cn.bwm.dao.AccountDao;
import cn.bwm.pojo.Account;
import cn.bwm.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author bwm
 */
@Service("accountService")
@Transactional(rollbackFor = Exception.class)
public class AccountServiceImpl implements AccountService {
    /*
        @Transactional 注解管理事务
        rollback-for 用于指定能够触发事务回滚的异常类型,如果有多个异常类型需要指定,各类型之间可以通过逗号分隔。
     */


    /**
     * 引入dao层
     */
    @Autowired
    @Qualifier("accountDao")
    private AccountDao accountDao;

    @Override
    public Account findAccountByName(String name) {
        return accountDao.findAccountByName(name);
    }

    @Override
    public void updateAccount(Account account) {
        accountDao.updateAccount(account);
    }

    @Override
   // @Transactional(rollbackFor = Exception.class)
    public void transfer(String out, String in, Double money) {
        //转出账户信息
        Account outAccount = accountDao.findAccountByName(out);
        System.out.println("转账前"+out+"的账户金额为:"+outAccount.getMoney());
        //转入账户信息
        Account inAccount = accountDao.findAccountByName(in);
        System.out.println("转账前"+in+"的账户金额为:"+inAccount.getMoney());
        //转账 入账操作
        outAccount.setMoney(outAccount.getMoney()-money);
        inAccount.setMoney(inAccount.getMoney()+money);
        //更新双方账户信息
        accountDao.updateAccount(outAccount);
        System.out.println("转账后"+out+"的账户金额为:"+outAccount.getMoney());
        //制造异常
        int i = 1 / 0 ;
        accountDao.updateAccount(inAccount);
        System.out.println("转账后"+in+"的账户金额为:"+inAccount.getMoney());
    }
}

2.8 业务层测试

package cn.bwm.service;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * @author bwm
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations ={"classpath:applicationContext.xml"})
public class AccountServiceTest {

    @Autowired
    @Qualifier("accountService")
    private AccountService accountService;

    @Test
    public void findAccountByName() {
        System.out.println(accountService.findAccountByName("李四"));
        System.out.println(accountService.findAccountByName("张三"));
    }

    @Test
    public void transfer() {
        accountService.transfer("李四","张三",10.0);
    }
}

项目结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-azGJKxDy-1591623123246)(C:\Users\40425\Desktop\daydayup\assets\1591545602000.png)]

ion.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**

  • @author bwm
    */
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations ={“classpath:applicationContext.xml”})
    public class AccountServiceTest {

    @Autowired
    @Qualifier(“accountService”)
    private AccountService accountService;

    @Test
    public void findAccountByName() {
    System.out.println(accountService.findAccountByName(“李四”));
    System.out.println(accountService.findAccountByName(“张三”));
    }

    @Test
    public void transfer() {
    accountService.transfer(“李四”,“张三”,10.0);
    }
    }




> 项目结构

[外链图片转存中...(img-azGJKxDy-1591623123246)]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值