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)]