博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Dao跨事务调用实现转账功能
阅读量:5133 次
发布时间:2019-06-13

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

1.首先在数据库当中创建数据库,并且创建它的 实现类

package com.beiwo.epet.entity;public class Account {    private int id;    private String name;    private int money;    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getMoney() {        return money;    }    public void setMoney(int money) {        this.money = money;    }}

2.导入jar包,并且 添加到构建路径

3.在这里采用的是C3P0数据源,并且导入它的固定格式文件c3p0-config.xml

    数据源

package com.beiwo.epet.util;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import javax.sql.DataSource;import com.mchange.v2.c3p0.ComboPooledDataSource;public class C3P0Util {		//C3P0数据源	private static ComboPooledDataSource dataSource=new ComboPooledDataSource();		public static DataSource getDataSource() {		return dataSource;	}			public static Connection getConn(){		try {			return dataSource.getConnection();		} catch (SQLException  e) {			throw new  RuntimeException(e);		}	}		public static Connection getConn2(){		Connection conn=null;				try {			conn=dataSource.getConnection();		} catch (Exception  e) {			e.printStackTrace();		}				return conn;	}		//释放连接	public static void realease(ResultSet rs,Statement stmt,Connection conn){		try {			if(null!=rs){				rs.close();			}		} catch (Exception e) {			// TODO: handle exception		}		try {			if(null!=stmt){				stmt.close();			}		} catch (Exception e) {			// TODO: handle exception		}		try {			if(null!=conn){				conn.close();			}		} catch (Exception e) {			// TODO: handle exception		}	}			}

     

  C3P0的固定格式

com.mysql.jdbc.Driver
jdbc:mysql:///day05
root
root
10
30
100
10

 

4.定义一个Dao接口(BaseDao)

package com.beiwo.epet.dao;import com.beiwo.epet.entity.Account;public interface  AccountDao {    /**     *      * @param fromName   	//谁转的     * @param toName  		// 转给谁     * @param money    		//转了多少钱     * @throws Exception     */    public void updateAccount(String fromName,String toName,int money)throws Exception;            /**     * 更新信息     * @param account     * @throws Exception     */    public void updateAccount(Account account)throws Exception;        /**     * 获取名字     * @param name     * @return     * @throws Exception     */    public Account findAccountByName(String name)throws Exception;}

 5.Dao的实现类

package com.beiwo.epet.dao.impl;import org.apache.commons.dbutils.QueryRunner;import org.apache.commons.dbutils.handlers.BeanHandler;import com.beiwo.epet.dao.AccountDao;import com.beiwo.epet.entity.Account;import com.beiwo.epet.util.C3P0Util;import com.beiwo.epet.util.TransactionManager;public class AccountDaoImpl implements AccountDao{    @Override    public void updateAccount(String fromName, String toName, int money) throws Exception{        QueryRunner qr=new QueryRunner(C3P0Util.getDataSource());                qr.update("UPDATE account SET money=money-? WHERE name=?",money,fromName);        qr.update("UPDATE account SET money=money+? WHERE name=?",money,toName);    }    @Override    public void updateAccount(Account account) throws Exception{        QueryRunner qr=new QueryRunner();        qr.update(TransactionManager.getConnection(),"UPDATE account SET money=? WHERE name=?", account.getMoney(),account.getName());    }    @Override    public Account findAccountByName(String name) throws Exception{        QueryRunner qr=new QueryRunner();        return qr.query(TransactionManager.getConnection(),"SELECT * FROM account WHERE name=?",new BeanHandler
(Account.class),name); } }

 6.定义一个服务层接口来实现转账功能

package com.beiwo.epet.service;public interface AccountService {    public void transfer(String formName,String toName,int money);    }

 7.实现服务层接口

package com.beiwo.epet.service.impl;import com.beiwo.epet.dao.AccountDao;import com.beiwo.epet.dao.impl.AccountDaoImpl;import com.beiwo.epet.entity.Account;import com.beiwo.epet.service.AccountService;import com.beiwo.epet.util.TransactionManager;public class AccountServiceImpl implements AccountService{    @Override    public void transfer(String formName, String toName, int money) {        AccountDao accountDao=new AccountDaoImpl();                 try {            ///开始一个事务,start transaction;            //获取转入和转出的账户对象            TransactionManager.startTransaction();                        Account fromAccount=accountDao.findAccountByName(formName);            Account toAccount=accountDao.findAccountByName(toName);                        //修改账户的各自金额            fromAccount.setMoney(fromAccount.getMoney()-money);            toAccount.setMoney(toAccount.getMoney()+money);                        //完成转账的操作            accountDao.updateAccount(fromAccount);                    //如果没有使用ThreadLocal,那么当我们添加这个异常的时候,下面的代码就不会执行,直接进入异常处理,两个事务要么都执行,要么都不执行             int i=2/0;                        accountDao.updateAccount(toAccount);                          TransactionManager.commitTransaction();                    } catch (Exception e) {            try {                TransactionManager.rollbackTransaction();;//事务的回滚            } catch (Exception e2) {                e2.printStackTrace();            }                    }finally{            try {                TransactionManager.close();            } catch (Exception e2) {                e2.printStackTrace();            }        }                    }    }

 8.再次过程中我们需要保证Connection是同一个Connection,,所以再定义一个管理类来保证是同一个Connection

package com.beiwo.epet.util;import java.sql.Connection;public class TransactionManager {    private static ThreadLocal
t1=new ThreadLocal
(); //获取连接 public static Connection getConnection(){ Connection conn=t1.get();//从当前线程中取出一个连接 if(null==conn){ conn=C3P0Util.getConn(); t1.set(conn);//把conn对象放入当前线程中去 } return conn; } //开始事务 public static void startTransaction(){ try { Connection conn=getConnection(); conn.setAutoCommit(false);//从当前线程中取出连接,并开始事务 } catch (Exception e) { e.printStackTrace(); } } //提交事务 public static void commitTransaction(){ try { Connection conn=getConnection(); conn.commit(); } catch (Exception e) { e.printStackTrace(); } } //回滚事务 public static void rollbackTransaction(){ try { Connection conn=getConnection(); conn.rollback(); } catch (Exception e) { e.printStackTrace(); } } //关闭连接 public static void close(){ try { Connection conn=getConnection(); conn.close(); t1.remove(); } catch (Exception e) { e.printStackTrace(); } } }

 9.最后一步就是测试,在此过程中我们没有使用main函数,所以我们自定义一个测试类来测试

 

package com.beiwo.epet.test;import org.junit.Test;import com.beiwo.epet.service.AccountService;import com.beiwo.epet.service.impl.AccountServiceImpl;public class TestTransfer {        @Test    public void test(){        AccountService accountService=new AccountServiceImpl();                accountService.transfer("aaa", "bbb", 100);            }}

 

数据库中原有的数据如下:

 

测试之后的结果如下:

 

转载于:https://www.cnblogs.com/houjiie/p/6196197.html

你可能感兴趣的文章
android开发之路05
查看>>
[leetcode] Triangle
查看>>
jq的each方法之退出循环与继续循环
查看>>
Servlet 浅析
查看>>
自动化通讯协定——现场总线
查看>>
Unity3D DoTween插件 的基本用法
查看>>
php操作excel表格的导入和导出
查看>>
Django signal
查看>>
java+jxls利用excel模版进行导出
查看>>
使用Golang实现的快速排序
查看>>
TestNG安装及配置
查看>>
(转载)OC学习篇之---Foundation框架中的NSDirctionary类以及NSMutableDirctionary类
查看>>
jQuery效果
查看>>
理解变量的作用域
查看>>
三层架构
查看>>
iview 路由权限判断的处理
查看>>
Sklearn环境搭建与常用包
查看>>
[转][Android]Android数据的四种存储方式
查看>>
js中typeof与instanceof用法小记
查看>>
理解$watch ,$apply 和 $digest --- 理解数据绑定过程
查看>>