使用spring模拟转账,并实现异常事务回滚

1、数据库准备

使用配置类配置数据源、模板、事务回滚

package cn.edu.aaa.utils;

import java.beans.PropertyVetoException;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
//import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.mchange.v2.c3p0.ComboPooledDataSource;
@Configuration
@ComponentScan("cn.edu.aaa")
@PropertySource("classpath:jdbc.properties")
@EnableTransactionManagement //让事务注释@Transactional起作用
public class MyConfiguration {
	@Value("${driver}")
	private String driver;
	@Value("${url}")
	private String url;
	@Value("${user}")
	private String user;
	@Value("${password}")
	private String password;
	@Bean
//数据源
	public ComboPooledDataSource combopooledDataSource() throws PropertyVetoException {
		ComboPooledDataSource dataSource=new ComboPooledDataSource();
		dataSource.setJdbcUrl(url);
		dataSource.setDriverClass(driver);
		dataSource.setUser("root");
		dataSource.setPassword("root");
		return dataSource;
		
	}
//模板
	@Bean
	public JdbcTemplate jdbcTemplate(@Autowired DataSource dataSource) {
		JdbcTemplate jdbcTemplate=new JdbcTemplate();
		jdbcTemplate.setDataSource(dataSource);
		return jdbcTemplate;
		
	}
//事务处理
	
	  @Bean
	 public PlatformTransactionManager transactionManager(@Autowired DataSource dataSource) {
		  DataSourceTransactionManager transactionManager=new DataSourceTransactionManager();
		  transactionManager.setDataSource(dataSource);
		  return transactionManager;
	}
	 
}

2、创建DAO层

DAO层负责数据库操作。定义了金额操作的方法

(1)定义接口

package cn.edu.aaa.dao;

public interface AccountDao {
	int addMoney(String aname,int money);
}

(2)接口实现类

package cn.edu.aaa.dao.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import cn.edu.aaa.dao.AccountDao;
@Repository("AccountDao")//声明这个类是一个Spring管理的bean,并且bean的名称为"AccountDao"。这样,其他Spring组件可以通过"AccountDao"这个名称来引用这个bean。
@Scope("singleton")//声明这个bean的作用域为单例。这意味着在整个Spring容器中,这个bean只有一个实例。
public class AccountDaoImpl implements AccountDao{
	@Autowired //通过@Autowired注解,自动装配一个JdbcTemplate的实例
	private JdbcTemplate jdbcTemplate;
	public int addMoney(String aname, int money) {
		// TODO Auto-generated method stub
		int i=jdbcTemplate.update("update accounts set money=money+? where aname=?",money,aname);//执行一个SQL更新操作,返回更新的记录数
		return i;
	}

}

3、创建Service层

 Service层是业务逻辑的核心。定义转账方法

(1)定义接口

package cn.edu.aaa.biz;

public interface AccountBiz {
	boolean transfer(String aname1,String aname2,Integer money);
}

(2)接口实现类。步骤:

1)转账方金额变少

2)收款方金额变多

3)转账过程中发生异常(事务回滚),输出false,数据表数据不变

package cn.edu.aaa.biz.impl;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import cn.edu.aaa.biz.AccountBiz;
import cn.edu.aaa.dao.AccountDao;

@Service("AccountBiz")
@Scope("singleton")
public class AccountBizImpl implements AccountBiz{
	@Autowired
	private AccountDao accountDao;
	@Transactional(isolation =Isolation.DEFAULT,propagation=Propagation.REQUIRED,readOnly=false)
	public boolean transfer(String aname1, String aname2, Integer money) {
		// TODO Auto-generated method stub

		try {
			accountDao.addMoney(aname1, (-1)*money);
			//System.out.println(1/0);  //通过开放这句语句,来测试是否对异常处理
			accountDao.addMoney(aname2, money);
			return true;
		}catch (Exception e) {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//让事务只回滚
			return false;
		}
	}

}

4、测试转账功能 

package cn.edu.aaa.test;

import javax.annotation.Resource;

import org.junit.Test;
import org.junit.experimental.theories.suppliers.TestedOn;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.PropertySource;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import cn.edu.aaa.biz.AccountBiz;
import cn.edu.aaa.utils.MyConfiguration;

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(classes=MyConfiguration.class)//导入配置类

public class AccountBizTest {
	@Autowired

	private AccountBiz accountBiz;
	@Test
	public void test() {
		System.out.println(accountBiz.transfer("superman", "spiderman", 500));
		
	}


}

结果正常,输出true,数据表内容变化

结果异常,输出false,数据表内容不变

 5、补充

pom.xml导入依赖

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>cn.edu.aaa</groupId>
  <artifactId>demo2</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <dependencies>
  	<dependency>
  		<groupId>org.springframework</groupId>
  		<artifactId>spring-context</artifactId>
  		<version>5.3.23</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.3.23</version>
  	</dependency>
  	
  	<dependency>
  		<groupId>org.aspectj</groupId>
  		<artifactId>aspectjweaver</artifactId>
  		<version>1.9.5</version>
  	</dependency>  
  	 
  	 <dependency>
  		<groupId>org.springframework</groupId>
  		<artifactId>spring-jdbc</artifactId>
  		<version>5.3.23</version>
  	</dependency>
  	<dependency>
  		<groupId>com.mchange</groupId>
  		<artifactId>c3p0</artifactId>
  		<version>0.9.5.4</version>
  	</dependency>
  	<dependency>
  		<groupId>mysql</groupId>
  		<artifactId>mysql-connector-java</artifactId>
  		<version>8.0.27</version>
  	</dependency>
  	<dependency>
  		<groupId>javax.annotation</groupId>
  		<artifactId>javax.annotation-api</artifactId>
  		<version>1.3.2</version>
  	</dependency>
  	
  	 
  	 
  </dependencies>
  
</project>

目录结构

  • 20
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mikuc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值