使用转账的例子来说明基于AOP的事务管理
1.导入jar包
2.创建数据库
/*Navicat MySQL Data Transfer
Source Server : localhost
Source Server Version : 50725
Source Host : localhost:3306
Source Database : springtx
Target Server Type : MYSQL
Target Server Version : 50725
File Encoding : 65001
Date: 2019-03-28 16:54:21*/
SET FOREIGN_KEY_CHECKS=0;--------------------------------Table structure for account------------------------------
DROP TABLE IF EXISTS`account`;CREATE TABLE`account` (
`id`int(11) NOT NULLAUTO_INCREMENT,
`username`varchar(50) DEFAULT NULL,
`money` int(11) DEFAULT NULL,PRIMARY KEY(`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;--------------------------------Records of account------------------------------
INSERT INTO `account` VALUES ('1', 'xiaoming', '10000');INSERT INTO `account` VALUES ('2', 'xiaohong', '10000');
3.编写dao层的代码
packageoyb.dao;public interfaceIAccountDao {public voidout(String outer, Integer money);public voidin(String inner, Integer money);
}
packageoyb.dao.impl;importorg.springframework.jdbc.core.support.JdbcDaoSupport;importoyb.dao.IAccountDao;public class AccountDaoImpl extends JdbcDaoSupport implementsIAccountDao {
@Overridepublic voidout(String outer, Integer money) {
String sql= "update account set money = money - ? where username = ?";this.getJdbcTemplate().update(sql,money,outer);
}
@Overridepublic voidin(String inner, Integer money) {
String sql= "update account set money = money + ? where username = ?";this.getJdbcTemplate().update(sql,money,inner);
}
}
4.编写业务层的代码
packageoyb.service;public interfaceIAccountService {public voidtransfer(String outer, String in, Integer money);
}
packageoyb.service.impl;importoyb.dao.IAccountDao;importoyb.service.IAccountService;public class AccountServiceImpl implementsIAccountService {//提供set方法,由spring注入
privateIAccountDao accountDao;public voidsetAccountDao(IAccountDao accountDao) {this.accountDao =accountDao;
}
@Overridepublic voidtransfer(String outer, String inner, Integer money) {
accountDao.out(outer,money);
accountDao.in(inner,money);
}
}
添加db.properties文件
driverClass=com.mysql.jdbc.Driver
jdbcUrl=jdbc:mysql:///springtx
user=root
password=123456
配置beans.xml文件
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
测试转账功能是否完好
importorg.junit.Test;importorg.springframework.context.ApplicationContext;importorg.springframework.context.support.ClassPathXmlApplicationContext;importoyb.dao.IAccountDao;importoyb.service.IAccountService;public classtest {
@Testpublic voidtest(){
ApplicationContext context= new ClassPathXmlApplicationContext("beans.xml");
IAccountService accountService= (IAccountService) context.getBean("accountService");
accountService.transfer("xiaoming","xiaohong",100);
}
}
测试的结果
基本的条件搭建好了之后,下面来讲基于AOP的事务配置,除了AOP的自动代理,还有工厂代理以及手动管理事务,后两者可作为了解,这里不涉及,主要还是掌握基于AOP的事务管理。
在配置事务管理前,我们可以看下如果业务类中的transfer方法出现了异常,数据库的结果会是怎样的。
我在转账的方法中加了一句int i = 10/0 这段会抛出异常的代码
可执行完测试的代码之后可以发现,xiaoming的钱虽然减少了,但是并未转入xiaohong的账户中,根据事务管理可知,如果出现了异常,应该回滚。
以上便是没有配置事务管理所会出现的结果
我们让xiaoming的账户恢复到之前的余额
修改beans.xml这个配置文件
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
此时在transfer方法中还有int 10/0 这段代码,所以仍存在异常,运行完测试类后,我们查看下数据库
可知事务确实是回滚了。
我们把int i =10/0这句代码删除,在运行测试方法查看下数据库
以上便是基于AOP的事务配置的例子