用了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)的更多相关文章

  1. 转账示例(三):service层面实现(线程管理Connection)(本例采用QueryRunner来执行sql语句,数据源为C3P0)

    缺点:Service层面还是不应该出现关于事务的操作1.自行创建C3P0Uti,account数据库,导入Jar包 2.Dao层面 接口: package com.learning.dao; impo ...

  2. 转账示例(二):service层面实现(本例采用QueryRunner来执行sql语句,数据源为C3P0)

    缺点:Service层面把Dao层面的开启事务操作完成了1.自行创建C3P0Uti,account数据库,导入Jar包 2.Dao层面 接口: package com.learning.dao; im ...

  3. 转账示例(一):Dao层面实现(本例采用QueryRunner来执行sql语句,数据源为C3P0)

    缺点:Dao层面把Service层面的操作完成了,不利于后期的代码修改和重构 1.自行创建C3P0Util account数据库 2.jar包 3.Dao层面 接口: package com.lear ...

  4. 在EF4.1的DBContext中实现事务处理(BeginTransaction)和直接执行SQL语句的示例

    在EF4.1的DBContext中实现事务处理(BeginTransaction)和直接执行SQL语句的示例 (2012-03-13 10:12:48) 转载▼   public ActionResu ...

  5. JDBC详解系列(四)之建立Stament和执行SQL语句

    建立Stament   在获得连接之后,我们就可以跟数据库进行交互了.   在JDBC中,我们发送SQL语句到数据库这些操作时通过Stament,Preparement,CallableStateme ...

  6. ucore操作系统学习(四) ucore lab4内核线程管理

    1. ucore lab4介绍 什么是进程? 现代操作系统为了满足人们对于多道编程的需求,希望在计算机系统上能并发的同时运行多个程序,且彼此间互相不干扰.当一个程序受制于等待I/O完成等事件时,可以让 ...

  7. Java--简单的Spring AOP配置以及AOP事物管理,JDK/GCLib动态代理

    一.看一下简单的通过XML的AOP配置 1.首先创建一个简单的Student类 public class Student { private Integer age; private String n ...

  8. SpringBoot | 第二十四章:日志管理之AOP统一日志

    前言 上一章节,介绍了目前开发中常见的log4j2及logback日志框架的整合知识.在很多时候,我们在开发一个系统时,不管出于何种考虑,比如是审计要求,或者防抵赖,还是保留操作痕迹的角度,一般都会有 ...

  9. Spring学习8-Spring事务管理(AOP/声明式式事务管理)

    一.基础知识普及 声明式事务的事务属性: 一:传播行为 二:隔离级别 三:只读提示 四:事务超时间隔 五:异常:指定除去RuntimeException其他回滚异常.  传播行为: 所谓事务的传播行为 ...

随机推荐

  1. mybatis系列笔记(3)---SqlMapConfig.xml解析

    SqlMapConfig.xml SqlMapConfig.xml是Mybatis的全局配置参数,关于他的具体用的有专门的MyBatis - API文档,这里面讲的非常清楚,所以我这里就挑几个讲下: ...

  2. Hibernate 迫切连接和普通连接的区别

    package com.baidu.test; import java.util.ArrayList;import java.util.LinkedHashSet;import java.util.L ...

  3. 学习HTML5一周的收获1

    HTML5的基本结构 学习了title标签(显示网站名称),link标签(链接文件,可做网页美化) 快捷键:Ctrl+/ 注释 学习[meta标签] 1.charset属性:单独使用,设置文档字符集编 ...

  4. 在.NET项目中使用PostSharp,使用CacheManager实现多种缓存框架的处理

    在前面几篇随笔中,介绍了PostSharp的使用,以及整合MemoryCache,<在.NET项目中使用PostSharp,实现AOP面向切面编程处理>.<在.NET项目中使用Pos ...

  5. HttpServletRequest 各种方法总结

    HttpServletRequest HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象 ...

  6. ehcache memcache redis 区别

    之前用过redis 和 memcache ,没有ehcache 的开发经验,最近也查阅不少文档和博客,写一些总结,也有不少内容总结与诸多博客中的博主总结:  Ehcache EhCache 是一个纯J ...

  7. 20144306《网络对抗》MAL_逆向与Bof基础

    实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串. 该程序同时包含另一个代码片段,getShe ...

  8. Python中闭包、装饰器的概念

    1.闭包(Closure)的概念: 内部函数中对enclosing作用域的变量进行引用 1 passline = 60 2 def func(val): 3 print('%x' % id(val)) ...

  9. ICC_lab总结——ICC_lab1:数据设置和基本流程

    ICC_lab总结 最近在学习后端的流程,做lab是最好不过了.但是有时候做过了lab,过了一段时间之后就会忘记,因此需要自己总结一下,加强印象. ICC_lab1:数据设置和基本流程 数据设置: 一 ...

  10. 【 js 性能优化】throttle 与 debounce 节流

    在看 underscore.js 源码的时候,接触到了这样两个方法,很有意思: 我先把实现的代码撂在下面,看不懂的可以先跳过,但是跳过可不是永远跳过哦- 一个是 throttle: _.throttl ...