博客
关于我
spring控制事务:声明式事务(注解)
阅读量:322 次
发布时间:2019-03-03

本文共 10802 字,大约阅读时间需要 36 分钟。

声明式事务(注解)

spring声明事务的方式,使用注解的方式

@Transactional

⚫ 名称:@Transactional

⚫ 类型:方法注解,类注解,接口注解
⚫ 位置:方法定义上方,类定义上方,接口定义上方
⚫ 作用:设置当前类/接口中所有方法或具体方法开启事务,并指定相关事务属性
⚫ 范例:

@Transactional(readOnly = false,timeout = -1,isolation = Isolation.DEFAULT,rollbackFor = {   ArithmeticException.class, IOException.class},noRollbackFor = {   },propagation = Propagation.REQUIRES_NEW)

tx:annotation-driven 标签用于开启事务的注解驱动

⚫ 名称:tx:annotation-driven

⚫ 类型:标签
⚫ 归属:beans标签
⚫ 作用:开启事务注解驱动,并指定对应的事务管理器
⚫ 范例:

声明式事务(纯注解驱动)

@EnableTransactionManagement 这个注解就是代替上面的标签

⚫ 名称:@EnableTransactionManagement

⚫ 类型:类注解
⚫ 位置:Spring注解配置类上方
⚫ 作用:开启注解驱动,等同XML格式中的注解驱动
⚫ 范例:

@Configuration@ComponentScan("com.fs")@PropertySource("classpath:jdbc.properties")@Import({   JDBCConfig.class,MyBatisConfig.class,TransactionManagerConfig.class})@EnableTransactionManagementpublic class SpringConfig {   }
public class TransactionManagerConfig {   @Beanpublic PlatformTransactionManager getTransactionManager(@Autowired DataSource dataSource){   return new DataSourceTransactionManager(dataSource);}}

代码演示(代码中注释为详细解释)

数据表account

在这里插入图片描述

构建maven项目

在这里插入图片描述

pom文件

4.0.0
com.fs
day04_spring_AOP_Transaction_02
1.0-SNAPSHOT
org.springframework
spring-context
5.1.9.RELEASE
org.springframework
spring-test
5.1.9.RELEASE
org.springframework
spring-jdbc
5.1.9.RELEASE
org.mybatis
mybatis-spring
2.0.1
org.mybatis
mybatis
3.5.5
mysql
mysql-connector-java
5.1.47
com.alibaba
druid
1.1.20
org.projectlombok
lombok
1.18.12
org.aspectj
aspectjweaver
1.9.5
junit
junit
4.12
test

jdbc.properties

jdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://192.168.93.132:3306/testjdbc.username=rootjdbc.password=root

编写配置类

SpringConfig

package com.fs.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;//表示这个类是一个spring的配置类,并将其存入到ioc容器中@Configuration/*开启扫描注解的那些包
*/@ComponentScan("com.fs")//引入其他的配置类@Import({ JdbcConfig.class,MybatisConfig.class,TransactionManagerConfig.class})//开启切面自动代理@EnableAspectJAutoProxy//开启声明式事务管理 相当于配置文件中的
@EnableTransactionManagementpublic class SpringConfig { }

JdbcConfig

package com.fs.config;import com.alibaba.druid.pool.DruidDataSource;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.PropertySource;/*
*/@PropertySource("classpath:jdbc.properties")public class JdbcConfig { //@Value("${Key}") @Value("${jdbc.driver}") private String driver; @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; /*
*/ //将返回的DruidDataSource交给ioc管理 @Bean public DruidDataSource getDruidDataSource(){ //创建DruidDataSource DruidDataSource druidDataSource = new DruidDataSource(); //给属性赋值,这个是上面从配置文件中依耐注入给属性的 druidDataSource.setDriverClassName(driver); druidDataSource.setUrl(url); druidDataSource.setUsername(username); druidDataSource.setPassword(password); //返回DruidDataSource,然后交给ioc管理 return druidDataSource; }}

MybatisConfig

package com.fs.config;import org.mybatis.spring.SqlSessionFactoryBean;import org.mybatis.spring.mapper.MapperScannerConfigurer;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import javax.sql.DataSource;public class MybatisConfig {       /*        
*/ @Bean public SqlSessionFactoryBean getSqlSessionFactoryBean(@Autowired DataSource dataSource){ //创建sql会话工厂类 //这里@Autowired也是从ioc拿DataSource SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); //从ioc容器中取出jdbcConfig中配置的druidDatasource sqlSessionFactoryBean.setDataSource(dataSource); //配置起别名 sqlSessionFactoryBean.setTypeAliasesPackage("com.fs.pojo"); return sqlSessionFactoryBean; } /*
*/ //创建MyBatis动态代理扫描类 @Bean public MapperScannerConfigurer getMapperScannerConfigurer(){ //创建映扫描配置类 MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer(); //设置动态代理扫描的dao的包 mapperScannerConfigurer.setBasePackage("com.fs.dao"); //交给spring管理 return mapperScannerConfigurer; }}

TransactionManagerConfig

package com.fs.config;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.jdbc.datasource.DataSourceTransactionManager;import org.springframework.transaction.PlatformTransactionManager;import javax.sql.DataSource;/*声明式事务配置类 */public class TransactionManagerConfig {       /*    
*/ @Bean public PlatformTransactionManager getTransactionManager(@Autowired DataSource dataSource){ //使用Spring的平台事务管理器,是一个接口,使用他的实现类构造器传递一个连接池 DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(); //传递一个连接池 dataSourceTransactionManager.setDataSource(dataSource); return dataSourceTransactionManager; }}

实体类

Account

package com.fs.pojo;import lombok.Data;@Datapublic class Account {       private Integer id;    private String name;    private Double money;}

Dao

AccountDao

package com.fs.dao;import com.fs.pojo.Account;import org.apache.ibatis.annotations.Param;import org.apache.ibatis.annotations.Select;import org.apache.ibatis.annotations.Update;import java.util.List;public interface AccountDao {       @Select("select * from account")    List
findAll();//查询所有 //根据名字修改money @Update("UPDATE account SET money = #{money} WHERE name = #{name}") void transferMoney(Account account); //根据名字查询账户信息 @Select("select * from account where name = #{name}") Account findAccountByName(@Param("name") String name);}

service

AccountService

package com.fs.service;import com.fs.pojo.Account;import org.springframework.transaction.annotation.Transactional;import java.util.List;/*在接口上配置@Transactional,那么他下面的实现类都会进行事务管理这个注解就相当于配置文件中的这些配置    
如果不写属性,该注解的默认配置为 @Transactional( readOnly = false, timeout = -1, isolation = Isolation.DEFAULT, rollbackFor = {ArithmeticException.class, IOException.class}, noRollbackFor = {}, propagation = Propagation.REQUIRES_NEW ) */public interface AccountService { List
findAll(); Account findAccountByName(String name); //对这个方法开启事务使用默认配置 @Transactional void transferMoneyAtoB(String aName,String bName,Integer money);}

AccountServiceImpl

package com.fs.service.impl;import com.fs.dao.AccountDao;import com.fs.pojo.Account;import com.fs.service.AccountService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import javax.sql.DataSource;import java.util.List;/*    
*/@Servicepublic class AccountServiceImpl implements AccountService { //从ioc获取MyBatis动态代理的accountDao实现类 @Autowired private AccountDao accountDao; @Autowired private DataSource dataSource; @Override public List
findAll() { return accountDao.findAll(); } @Override public Account findAccountByName(String name) { return accountDao.findAccountByName(name); } //转账的业务实现 @Override public void transferMoneyAtoB(String aName, String bName, Integer money) { //先查出两个人的数据 Account aAccount = accountDao.findAccountByName(aName); Account bAccount = accountDao.findAccountByName(bName); //然后a减钱,b加钱 aAccount.setMoney(aAccount.getMoney()-money); bAccount.setMoney(bAccount.getMoney()+money); //然后调用转账方法(sql语句为更新账户) accountDao.transferMoney(aAccount); //制作一个异常// int i = 1/0; accountDao.transferMoney(bAccount); }}

测试类

package com.fs.service.impl;import com.fs.config.SpringConfig;import com.fs.pojo.Account;import com.fs.service.AccountService;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import java.util.List;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(classes = SpringConfig.class)public class AccountServiceImplTest {       @Autowired    private AccountService accountService;    //测试查询所有方法    @Test    public void findAll() {           List
all = accountService.findAll(); System.out.println(all); } //测试转账方法已经使用@Transactional绑定事务 @Test public void transferMoneyAtoB() { //测试转账方法 accountService.transferMoneyAtoB("小付","小花",100); }}

执行效果

业务层转账方法正常运行成功后数据表数据

由于我们测试代码中是小付向小花转账100元,代码执行成功后应该小付900,小花1100

在这里插入图片描述
业务层转账方法我们给制作一个异常1/0 的/ by zero异常,
运存测试转账方法控制台输出
在这里插入图片描述
数据库中表的数据
小付原本900,小花1100,我们进行了转账业务,但是制作了异常,事务会进行回滚,所以金额不会发生变化

在这里插入图片描述

转载地址:http://uqsm.baihongyu.com/

你可能感兴趣的文章
Mysql--逻辑架构
查看>>
MySql-2019-4-21-复习
查看>>
mysql-5.6.17-win32免安装版配置
查看>>
mysql-5.7.18安装
查看>>
MySQL-Buffer的应用
查看>>
mysql-cluster 安装篇(1)---简介
查看>>
mysql-connector-java.jar乱码,最新版mysql-connector-java-8.0.15.jar,如何愉快的进行JDBC操作...
查看>>
mysql-connector-java各种版本下载地址
查看>>
mysql-EXPLAIN
查看>>
MySQL-Explain的详解
查看>>
mysql-group_concat
查看>>
MySQL-redo日志
查看>>
MySQL-【1】配置
查看>>
MySQL-【4】基本操作
查看>>
Mysql-丢失更新
查看>>
Mysql-事务阻塞
查看>>
Mysql-存储引擎
查看>>
mysql-开启慢查询&所有操作记录日志
查看>>
MySQL-数据目录
查看>>
MySQL-数据页的结构
查看>>