转账示例(四):service层面实现(线程管理Connection,AOP思想,动态代理)(本例采用QueryRunner来执行sql语句,数据源为C3P0)
用了AOP(面向切面编程),实现动态代理,service层面隐藏了开启事务。
1.自行创建C3P0Uti,account数据库,导入Jar包
2.Dao层面
接口:
package com.learning.dao;
import com.learning.domain.Account;
public interface AccountDao {
/**
* 转账
* @param fromname 转出用户
* @param toname 转入用户
* @param money 转账金额
*/
@Deprecated
public void updateAccount(String fromname,String toname,double money)throws Exception;
/**
* 根据账户信息修改金额
* @param accout
*/
public void updateAccout(Account accout) throws Exception;
/**
* 根据用户名查找账户信息
* @param name
* @return
* @throws Exception
*/
public Account findAccountByName(String name)throws Exception;
}
实现类:
package com.learning.dao.impl; import java.sql.Connection;
import java.sql.SQLException; import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler; import com.learning.dao.AccountDao;
import com.learning.domain.Account;
import com.learning.util.C3P0Util; public class AccountDaoImpl implements AccountDao { private Connection conn; public AccountDaoImpl(Connection conn) {
this.conn = conn;
} public void updateAccount(String fromname, String toname, double money) throws Exception {
//创建一个QueryRunner对象
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);
} public void updateAccout(Account account) throws Exception {
QueryRunner qr = new QueryRunner();
qr.update(conn,"update account set money=? where name=?",account.getMoney(),account.getName());
} public Account findAccountByName(String name) throws Exception {
QueryRunner qr = new QueryRunner();
return qr.query(conn,"select * from account where name=?", new BeanHandler<Account>(Account.class),name);
} }
3.Service层面
接口:
package com.learning.service;
public interface AccountService {
/**
* 转账
* @param fromname 转出用户
* @param toname 转入用户
* @param money 转账金额
*/
public void transfer(String fromname,String toname,double money);
}
实现类:
package com.learning.service.impl; import java.sql.Connection;
import java.sql.SQLException; import com.learning.dao.AccountDao;
import com.learning.dao.impl.AccountDaoImpl;
import com.learning.domain.Account;
import com.learning.service.AccountService;
import com.learning.util.C3P0Util;
import com.learning.util.ManagerThreadLocal; public class AccountServiceImpl implements AccountService { public void transfer(String fromname, String toname, double money) throws Exception {
// ad.updateAccount(fromname, toname, money);
AccountDao ad = new AccountDaoImpl(); //分别得到转出和转入账户对象
Account fromAccount = ad.findAccountByName(fromname);
Account toAccount = ad.findAccountByName(toname); //修改账户各自的金额
fromAccount.setMoney(fromAccount.getMoney()-money);
toAccount.setMoney(toAccount.getMoney()+money); //完成转账操作
ad.updateAccout(fromAccount);
int i = 10/0;
ad.updateAccout(toAccount); } }
4.创建ManagerThreadLocal管理Connection
AccountDaoImpl();
try {
ManagerThreadLocal.startTransacation();//begin
//分别得到转出和转入账户对象
Account fromAccount = ad.findAccountByName(fromname);
Account toAccount = ad.findAccountByName(toname);
//修改账户各自的金额
fromAccount.setMoney(fromAccount.getMoney()-money);
toAccount.setMoney(toAccount.getMoney()+money);
//完成转账操作
ad.updateAccout(fromAccount);
// int i = 10/0;
ad.updateAccout(toAccount);
ManagerThreadLocal.commit();//提交事务
} catch (Exception e) {
try {
ManagerThreadLocal.rollback();//回滚事务
} catch (Exception e1) {
e1.printStackTrace();
}
}finally{
try {
ManagerThreadLocal.close();
} catch (Exception e) {
e.printStackTrace();
}//关闭
}
}package com.learning.util;
import java.sql.Connection;
import java.sql.SQLException;
public class ManagerThreadLocal {
private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
//得到一个连接
public static Connection getConnection(){
Connection conn = tl.get();//从当前线程中取出一个连接
if(conn==null){
conn = C3P0Util.getConnection();//从池中取出一个
tl.set(conn);//把conn对象放入到当前线程对象中
}
return conn;
}
//开始事务
public static void startTransacation(){
try {
Connection conn = getConnection();
conn.setAutoCommit(false);//从当前线程对象中取出的连接,并开始事务
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void commit(){
try {
getConnection().commit();//提交事务
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void rollback(){
try {
getConnection().rollback();//回滚事务
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void close(){
try {
getConnection().close();//把连接放回池中
tl.remove();//把当前线程对象中的conn移除
} catch (SQLException e) {
e.printStackTrace();
}
}
}
5.创建ProxyFactory(代理类)
package com.learning.util; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import com.learning.service.AccountService;
import com.learning.service.impl.AccountServiceImpl; public class ProxyFactory {
//方法返回一个代理对象
public static AccountService getAccountService(){
final AccountService as= new AccountServiceImpl(); AccountService proxy = (AccountService) Proxy.newProxyInstance(as.getClass().getClassLoader(), as.getClass().getInterfaces(), new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object invoke = null;
try { ManagerThreadLocal.startTransacation();//begin
//执行的是真实对象的转账方法
invoke = method.invoke(as, args); ManagerThreadLocal.commit();//提交事务
} catch (Exception e) {
try {
ManagerThreadLocal.rollback();//回滚事务
} catch (Exception e1) {
e1.printStackTrace();
}
}finally{
try {
ManagerThreadLocal.close();
} catch (Exception e) {
e.printStackTrace();
}//关闭
}
return invoke;
}
});
return proxy;
}
}
6.Test
package com.learning.test; import com.learning.service.AccountService;
import com.learning.service.impl.AccountServiceImpl;
import com.learning.util.ObjectFactory; public class TestTransfer { /**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
AccountService as = ProxyFactory.getAccountService();
as.transfer("aaa", "bbb", 100);
} }
转账示例(四):service层面实现(线程管理Connection,AOP思想,动态代理)(本例采用QueryRunner来执行sql语句,数据源为C3P0)的更多相关文章
- 转账示例(三):service层面实现(线程管理Connection)(本例采用QueryRunner来执行sql语句,数据源为C3P0)
缺点:Service层面还是不应该出现关于事务的操作1.自行创建C3P0Uti,account数据库,导入Jar包 2.Dao层面 接口: package com.learning.dao; impo ...
- 转账示例(二):service层面实现(本例采用QueryRunner来执行sql语句,数据源为C3P0)
缺点:Service层面把Dao层面的开启事务操作完成了1.自行创建C3P0Uti,account数据库,导入Jar包 2.Dao层面 接口: package com.learning.dao; im ...
- 转账示例(一):Dao层面实现(本例采用QueryRunner来执行sql语句,数据源为C3P0)
缺点:Dao层面把Service层面的操作完成了,不利于后期的代码修改和重构 1.自行创建C3P0Util account数据库 2.jar包 3.Dao层面 接口: package com.lear ...
- 在EF4.1的DBContext中实现事务处理(BeginTransaction)和直接执行SQL语句的示例
在EF4.1的DBContext中实现事务处理(BeginTransaction)和直接执行SQL语句的示例 (2012-03-13 10:12:48) 转载▼ public ActionResu ...
- JDBC详解系列(四)之建立Stament和执行SQL语句
建立Stament 在获得连接之后,我们就可以跟数据库进行交互了. 在JDBC中,我们发送SQL语句到数据库这些操作时通过Stament,Preparement,CallableStateme ...
- ucore操作系统学习(四) ucore lab4内核线程管理
1. ucore lab4介绍 什么是进程? 现代操作系统为了满足人们对于多道编程的需求,希望在计算机系统上能并发的同时运行多个程序,且彼此间互相不干扰.当一个程序受制于等待I/O完成等事件时,可以让 ...
- Java--简单的Spring AOP配置以及AOP事物管理,JDK/GCLib动态代理
一.看一下简单的通过XML的AOP配置 1.首先创建一个简单的Student类 public class Student { private Integer age; private String n ...
- SpringBoot | 第二十四章:日志管理之AOP统一日志
前言 上一章节,介绍了目前开发中常见的log4j2及logback日志框架的整合知识.在很多时候,我们在开发一个系统时,不管出于何种考虑,比如是审计要求,或者防抵赖,还是保留操作痕迹的角度,一般都会有 ...
- Spring学习8-Spring事务管理(AOP/声明式式事务管理)
一.基础知识普及 声明式事务的事务属性: 一:传播行为 二:隔离级别 三:只读提示 四:事务超时间隔 五:异常:指定除去RuntimeException其他回滚异常. 传播行为: 所谓事务的传播行为 ...
随机推荐
- PDO预处理语句规避SQL注入攻击
所谓SQL注入式攻击,就是攻击者把SQL命令插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令.在某些表单中,用户输入的内容直接用来构造(或者影响)动态SQL命令,或作为存 ...
- 谈谈事件对象-event
JavaScript 中的事件对象(event) 当我们每次触发一种事件(如点击事件),我们会在回调函数中传入事件对象event.今天就来来谈谈. 1.当我们想判断当前事件是我们想要的事件类型时,可以 ...
- 大型ERP系统在线体验
ERP简单说明: AIO7构建了基于SOA三层架构的管理软件平台.客户通过网络即可得到ERP服务,不用安装服务器.不用建立数据中心.不用安装软件.无需专业IT支持,任何上网设备就可以使用高性能.功能集 ...
- 如何更新 OpenStack 组件?- 每天5分钟玩转 OpenStack(161)
这是 OpenStack 实施经验分享系列的第 11 篇. 本节教大家更新 OpenStack 组件的方法.请注意,是更新(Update)而不是升级(Upgrade).更新是给组件打补丁,版本不变:而 ...
- DOM基础(二)
在我之前写的DOM基础(一)的文章中提到过兼容性的问题,也就是在获取标签间文本信息的时候,早期的火狐版本是不支持innerText的,只支持textContent ,现在的火狐浏览器两者都支持.而IE ...
- 小白该怎么学《马哥Linux从入门到精通》
首先,必须说明我已经不是小白啦~现在的我在国内某独角兽担任运维工程师,带着一个四人小团队,在运维方面也算是有些心得,勉强过来回答一下这个问题,就算抛砖引玉了. 所有人都是从小白阶段过来的,我=也经历过 ...
- 1637: [Usaco2007 Mar]Balanced Lineup
1637: [Usaco2007 Mar]Balanced Lineup Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 393 Solved: 263[ ...
- 挂接命令(mount) 【转】
收藏些文章,以后可能有用,文章出自:http://tutu.spaces.eepw.com.cn/articles/article/item/70737 挂接命令(mount) 首先,介绍一下挂接(m ...
- js数组,字符串常用方法汇总(面试必备)
字符串: 1.concat() – 将两个或多个字符的文本组合起来,返回一个新的字符串. 2.indexOf() – 返回字符串中一个子串第一处出现的索引.如果没有匹配项,返回 -1 . 3.ch ...
- android学习——环境的搭建
1.安装JDK(java开发工具箱) 下载地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html(根据自己需要下载) ...