事务管理,AOP(1)
实现转账服务的时候,假如有异常怎么办呢?
我们先来看下面这段代码
User source =iDao.getUserById(from);
User target =iDao.getUserById(to);
source.setUsmoney(source.getUsmoney()-money);
target.setUsmoney(target.getUsmoney()+money);
iDao.updateUser(source);//到这里都是正常操作,source已经扣钱了
int i = 1/0;//但是由于到
iDao.updateUser(target);
这段代码,需要完成转账的服务,但是由于异常,最后一步就不会被执行
用户 | 来时的钱 | 完成操作的钱 |
---|---|---|
source | 100 | 80 |
target | 100 | 100 |
这样来源用户就会不明不白的丢失钱钱
这个时候就需要事务的管理
import com.ConnectionUtil;
import java.sql.SQLException;
/**
* 与业务相关的工具类
*/
public class TranslationManager {
private ConnectionUtil connectionUtil;//这个我是用sping来注入的
public void setConnectionUtil(ConnectionUtil connectionUtil) {
this.connectionUtil = connectionUtil;
}
public void beginTranslation(){
try {
connectionUtil.getConnection().setAutoCommit(false);
} catch (SQLException e) {
e.printStackTrace();
}
}
public void commit(){
try {
connectionUtil.getConnection().commit();
} catch (SQLException e) {
e.printStackTrace();
}
}
public void rollback(){
try {
connectionUtil.getConnection().rollback();
} catch (SQLException e) {
e.printStackTrace();
}
}
public void release(){
try {
connectionUtil.getConnection().close();
//把当前的连接还回线程中
connectionUtil.removeConnection();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
创建了一个事务管理类,以及connection绑定线程的类
import javax.sql.DataSource;
import java.sql.Connection;
public class ConnectionUtil {
//从线程中获取一个链接然后绑定
private ThreadLocal<Connection> t1 = new ThreadLocal<Connection>();
private DataSource dataSource;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public Connection getConnection(){
Connection connection = t1.get();
//
try{
if(connection==null){
//从数据库获得一个链接
connection = dataSource.getConnection();
t1.set(connection);
}
}catch (Exception e){
throw new RuntimeException(e);
}
return connection;
}
public void removeConnection(){
t1.remove();
}
}
在dao层获得connection,所有dao的基类以及实现类
public class BaseDao {
@Autowired
ConnectionUtil connectionUtil;
public void setConnectionUtil(ConnectionUtil connectionUtil) {
this.connectionUtil = connectionUtil;
}
public Connection getConnection(){
return connectionUtil.getConnection();
}
}
package com;
import com.pojo.User;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ArrayHandler;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
import java.sql.SQLException;
import java.util.Arrays;
@Component(value = "com.DaoImpl")
public class DaoImpl extends BaseDao implements IDao{
@Autowired
QueryRunner queryRunner;
public static void main(String[] args) throws SQLException {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
IDao dao = context.getBean("com.DaoImpl", IDao.class);
//dao.insertUser(new User(1,"嘻嘻嘻",100));
//dao.updateUser(new User(1,"吃果子",120));
System.out.println(dao.getUserById(1));
}
public void query(){
try{
Object o[] =queryRunner.query(getConnection(),"Select * from User" ,new ArrayHandler());
System.out.println(Arrays.toString(o));
}catch (Exception e){
e.printStackTrace();
}
}
public User getUserById(int id){
User user = null;
try{
user = queryRunner.query(getConnection(),"Select * from testmoney where usid = ?",new BeanHandler<User>(User.class),id);
}catch (Exception e){
e.printStackTrace();
}
return user;
}
public void insertUser(User user){
try {
queryRunner.update(getConnection(),"insert into testmoney(usname,usmoney) values (?,?)",user.getUsname(),user.getUsmoney());
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public void updateUser(User user){
try {
queryRunner.update(getConnection(),"update testmoney set usname = ?, usmoney = ? where usid = ?",
user.getUsname(),user.getUsmoney(),user.getUsid());
} catch (SQLException e) {
e.printStackTrace();
}
}
}
最后在service中进行事务管理
public class UserService implements IUserService {
@Autowired
IDao iDao;
@Autowired
TranslationManager translationManager;
public void sendMoney(int from, int to, int money) {
try{
translationManager.beginTranslation();//开启事务
User source =iDao.getUserById(from);
User target =iDao.getUserById(to);
source.setUsmoney(source.getUsmoney()-money);
target.setUsmoney(target.getUsmoney()+money);
iDao.updateUser(source);
int i = 1/0;
iDao.updateUser(target);
translationManager.commit();//提交事务
}catch (Exception e){
translationManager.rollback();//回滚处理异常
throw new RuntimeException(e);
}finally {
translationManager.release();//释放连接
}
}
}
总的结构流程图。