
动态代理——事务处理
发布日期:2021-05-10 19:06:19
浏览次数:32
分类:精选文章
本文共 17644 字,大约阅读时间需要 58 分钟。
事务控制应该都是在业务层
连接的工具类,它用于从数据源中获取一个连接,并且实现和线程的绑定
动态代理
pom.xml
4.0.0 com.dym day03_eesy_01account 1.0-SNAPSHOT org.apache.maven.plugins maven-compiler-plugin 1.6 1.6 jar org.springframework spring-context 5.0.2.RELEASE org.springframework spring-test 5.0.2.RELEASE commons-dbutils commons-dbutils 1.4 mysql mysql-connector-java 5.1.6 c3p0 c3p0 0.9.1.2 junit junit 4.12
Account.java
package com.itheima.domain;import java.io.Serializable;/** * 账户的实体类 */public class Account implements Serializable { private Integer id; private String name; private Float money; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Float getMoney() { return money; } public void setMoney(Float money) { this.money = money; } @Override public String toString() { return "Account{" + "id=" + id + ", name='" + name + '\'' + ", money=" + money + '}'; }}
ConnectionUtils.java
package com.itheima.utils;import javax.sql.DataSource;import java.sql.Connection;/** * 连接的工具类,它用于从数据源中获取一个连接,并且实现和线程的绑定 */public class ConnectionUtils { private ThreadLocaltl = new ThreadLocal (); private DataSource dataSource; public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } /** * 获取当前线程上的连接 * @return */ public Connection getThreadConnection() { try{ //1.先从ThreadLocal上获取 Connection conn = tl.get(); //2.判断当前线程上是否有连接 if (conn == null) { //3.从数据源中获取一个连接,并且存入ThreadLocal中 conn = dataSource.getConnection(); tl.set(conn); } //4.返回当前线程上的连接 return conn; }catch (Exception e){ throw new RuntimeException(e); } } /** * 把连接和线程解绑 */ public void removeConnection(){ tl.remove(); }}
TransactionManager.java
package com.itheima.utils;/** * 和事务管理相关的工具类,它包含了,开启事务,提交事务,回滚事务和释放连接 */public class TransactionManager { private ConnectionUtils connectionUtils; public void setConnectionUtils(ConnectionUtils connectionUtils) { this.connectionUtils = connectionUtils; } /** * 开启事务 */ public void beginTransaction(){ try { connectionUtils.getThreadConnection().setAutoCommit(false); }catch (Exception e){ e.printStackTrace(); } } /** * 提交事务 */ public void commit(){ try { connectionUtils.getThreadConnection().commit(); }catch (Exception e){ e.printStackTrace(); } } /** * 回滚事务 */ public void rollback(){ try { connectionUtils.getThreadConnection().rollback(); }catch (Exception e){ e.printStackTrace(); } } /** * 释放连接 */ public void release(){ try { connectionUtils.getThreadConnection().close();//还回连接池中 connectionUtils.removeConnection(); }catch (Exception e){ e.printStackTrace(); } }}
IAccountDao.java
package com.itheima.dao;import com.itheima.domain.Account;import java.util.List;/** * 账户的持久层接口 */public interface IAccountDao { /** * 查询所有 * @return */ ListfindAllAccount(); /** * 查询一个 * @return */ Account findAccountById(Integer accountId); /** * 保存 * @param account */ void saveAccount(Account account); /** * 更新 * @param account */ void updateAccount(Account account); /** * 删除 * @param acccountId */ void deleteAccount(Integer acccountId); /** * 根据名称查询账户 * @param accountName * @return 如果有唯一的一个结果就返回,如果没有结果就返回null * 如果结果集超过一个就抛异常 */ Account findAccountByName(String accountName);}
AccountDaoImpl.java
package com.itheima.dao.impl;import com.itheima.dao.IAccountDao;import com.itheima.domain.Account;import com.itheima.utils.ConnectionUtils;import org.apache.commons.dbutils.QueryRunner;import org.apache.commons.dbutils.handlers.BeanHandler;import org.apache.commons.dbutils.handlers.BeanListHandler;import java.util.List;/** * 账户的持久层实现类 */public class AccountDaoImpl implements IAccountDao { private QueryRunner runner; private ConnectionUtils connectionUtils; public void setRunner(QueryRunner runner) { this.runner = runner; } public void setConnectionUtils(ConnectionUtils connectionUtils) { this.connectionUtils = connectionUtils; } @Override public ListfindAllAccount() { try{ return runner.query(connectionUtils.getThreadConnection(),"select * from account",new BeanListHandler (Account.class)); }catch (Exception e) { throw new RuntimeException(e); } } @Override public Account findAccountById(Integer accountId) { try{ return runner.query(connectionUtils.getThreadConnection(),"select * from account where id = ? ",new BeanHandler (Account.class),accountId); }catch (Exception e) { throw new RuntimeException(e); } } @Override public void saveAccount(Account account) { try{ runner.update(connectionUtils.getThreadConnection(),"insert into account(name,money)values(?,?)",account.getName(),account.getMoney()); }catch (Exception e) { throw new RuntimeException(e); } } @Override public void updateAccount(Account account) { try{ runner.update(connectionUtils.getThreadConnection(),"update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId()); }catch (Exception e) { throw new RuntimeException(e); } } @Override public void deleteAccount(Integer accountId) { try{ runner.update(connectionUtils.getThreadConnection(),"delete from account where id=?",accountId); }catch (Exception e) { throw new RuntimeException(e); } } @Override public Account findAccountByName(String accountName) { try{ List accounts = runner.query(connectionUtils.getThreadConnection(),"select * from account where name = ? ",new BeanListHandler (Account.class),accountName); if(accounts == null || accounts.size() == 0){ return null; } if(accounts.size() > 1){ throw new RuntimeException("结果集不唯一,数据有问题"); } return accounts.get(0); }catch (Exception e) { throw new RuntimeException(e); } }}
IAccountService.java
package com.itheima.service;import com.itheima.domain.Account;import java.util.List;/** * 账户的业务层接口 */public interface IAccountService { /** * 查询所有 * @return */ ListfindAllAccount(); /** * 查询一个 * @return */ Account findAccountById(Integer accountId); /** * 保存 * @param account */ void saveAccount(Account account); /** * 更新 * @param account */ void updateAccount(Account account); /** * 删除 * @param acccountId */ void deleteAccount(Integer acccountId); /** * 转账 * @param sourceName 转出账户名称 * @param targetName 转入账户名称 * @param money 转账金额 */ void transfer(String sourceName, String targetName, Float money); //void test();//它只是连接点,但不是切入点,因为没有被增强}
AccountServiceImpl.java
package com.itheima.service.impl;import com.itheima.dao.IAccountDao;import com.itheima.domain.Account;import com.itheima.service.IAccountService;import java.util.List;/** * 账户的业务层实现类 */public class AccountServiceImpl implements IAccountService{ private IAccountDao accountDao; public void setAccountDao(IAccountDao accountDao) { this.accountDao = accountDao; } @Override public ListfindAllAccount() { return accountDao.findAllAccount(); } @Override public Account findAccountById(Integer accountId) { return accountDao.findAccountById(accountId); } @Override public void saveAccount(Account account) { accountDao.saveAccount(account); } @Override public void updateAccount(Account account) { accountDao.updateAccount(account); } @Override public void deleteAccount(Integer acccountId) { accountDao.deleteAccount(acccountId); } @Override public void transfer(String sourceName, String targetName, Float money) { System.out.println("transfer...."); //2.1 根据名称查询转出账户 Account source = accountDao.findAccountByName(sourceName); //2.2 根据名称查询转入账户 Account target = accountDao.findAccountByName(targetName); //2.3 转出账户减钱 source.setMoney(source.getMoney()-money); //2.4 转入账户加钱 target.setMoney(target.getMoney()+money); //2.5 更新转出账户 accountDao.updateAccount(source); //2.6 更新转入账户 accountDao.updateAccount(target); }}
AccountServiceImpl_OLD.java
package com.itheima.service.impl;import com.itheima.dao.IAccountDao;import com.itheima.domain.Account;import com.itheima.service.IAccountService;import com.itheima.utils.TransactionManager;import java.util.List;/** * 账户的业务层实现类 * * 事务控制应该都是在业务层 */public class AccountServiceImpl_OLD implements IAccountService{ private IAccountDao accountDao; private TransactionManager txManager; public void setTxManager(TransactionManager txManager) { this.txManager = txManager; } public void setAccountDao(IAccountDao accountDao) { this.accountDao = accountDao; } @Override public ListfindAllAccount() { try { //1.开启事务 txManager.beginTransaction(); //2.执行操作 List accounts = accountDao.findAllAccount(); //3.提交事务 txManager.commit(); //4.返回结果 return accounts; }catch (Exception e){ //5.回滚操作 txManager.rollback(); throw new RuntimeException(e); }finally { //6.释放连接 txManager.release(); } } @Override public Account findAccountById(Integer accountId) { try { //1.开启事务 txManager.beginTransaction(); //2.执行操作 Account account = accountDao.findAccountById(accountId); //3.提交事务 txManager.commit(); //4.返回结果 return account; }catch (Exception e){ //5.回滚操作 txManager.rollback(); throw new RuntimeException(e); }finally { //6.释放连接 txManager.release(); } } @Override public void saveAccount(Account account) { try { //1.开启事务 txManager.beginTransaction(); //2.执行操作 accountDao.saveAccount(account); //3.提交事务 txManager.commit(); }catch (Exception e){ //4.回滚操作 txManager.rollback(); }finally { //5.释放连接 txManager.release(); } } @Override public void updateAccount(Account account) { try { //1.开启事务 txManager.beginTransaction(); //2.执行操作 accountDao.updateAccount(account); //3.提交事务 txManager.commit(); }catch (Exception e){ //4.回滚操作 txManager.rollback(); }finally { //5.释放连接 txManager.release(); } } @Override public void deleteAccount(Integer acccountId) { try { //1.开启事务 txManager.beginTransaction(); //2.执行操作 accountDao.deleteAccount(acccountId); //3.提交事务 txManager.commit(); }catch (Exception e){ //4.回滚操作 txManager.rollback(); }finally { //5.释放连接 txManager.release(); } } @Override public void transfer(String sourceName, String targetName, Float money) { try { //1.开启事务 txManager.beginTransaction(); //2.执行操作 //2.1根据名称查询转出账户 Account source = accountDao.findAccountByName(sourceName); //2.2根据名称查询转入账户 Account target = accountDao.findAccountByName(targetName); //2.3转出账户减钱 source.setMoney(source.getMoney()-money); //2.4转入账户加钱 target.setMoney(target.getMoney()+money); //2.5更新转出账户 accountDao.updateAccount(source); int i=1/0; //2.6更新转入账户 accountDao.updateAccount(target); //3.提交事务 txManager.commit(); }catch (Exception e){ //4.回滚操作 txManager.rollback(); e.printStackTrace(); }finally { //5.释放连接 txManager.release(); } }}
BeanFactory.java
package com.itheima.factory;import com.itheima.service.IAccountService;import com.itheima.utils.TransactionManager;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;/** * 用于创建Service的代理对象的工厂 */public class BeanFactory { private IAccountService accountService; private TransactionManager txManager; public void setTxManager(TransactionManager txManager) { this.txManager = txManager; } public final void setAccountService(IAccountService accountService) { this.accountService = accountService; } /** * 获取Service代理对象 * @return */ public IAccountService getAccountService() { return (IAccountService)Proxy.newProxyInstance(accountService.getClass().getClassLoader(), accountService.getClass().getInterfaces(), new InvocationHandler() { /** * 添加事务的支持 * * @param proxy * @param method * @param args * @return * @throws Throwable */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if("test".equals(method.getName())){ return method.invoke(accountService,args); } Object rtValue = null; try { //1.开启事务 txManager.beginTransaction(); //2.执行操作 rtValue = method.invoke(accountService, args); //3.提交事务 txManager.commit(); //4.返回结果 return rtValue; } catch (Exception e) { //5.回滚操作 txManager.rollback(); throw new RuntimeException(e); } finally { //6.释放连接 txManager.release(); } } }); }}
bean.xml
AccountServiceTest.java
package com.itheima.test;import com.itheima.service.IAccountService;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;/** * 使用Junit单元测试:测试我们的配置 */@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = "classpath:bean.xml")public class AccountServiceTest { @Autowired @Qualifier("proxyAccountService") private IAccountService as; @Test public void testTransfer(){ as.transfer("aaa","bbb",100f); }}
发表评论
最新留言
初次前来,多多关照!
[***.217.46.12]2025年04月22日 11时15分31秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
为汽车新零售注入活力,瓜子二手车严选直卖店落地长沙
2021-05-10
Pytorch深度学习框架YOLOv3目标检测学习笔记(五)——输入输出工程实现
2021-05-10
VS中Qt项目汉字和UTF-8编码转换
2021-05-10
第007课 裸机开发步骤和工具使用(SourceInght NotePad++使用)
2021-05-10
STL使用——map/multimap容器
2021-05-10
android 开机启动流程分析(13)Zygote的分裂
2021-05-10
简单理解vuex原理
2021-05-10
ES6之函数的扩展
2021-05-10
发布订阅模式与观察者模式
2021-05-10
java.lang.NoSuchMethodError 错误的原因及解决方法
2021-05-10
马王堆出土道德经原文(非删改本)
2021-05-10
java从入门到精通----servlet11
2021-05-10
MySQL复习09-触发器
2021-05-10
JS实现禁止浏览器后退返回上一页
2021-05-10
redis ③ -java客户端连接redis
2021-05-10
torch.meshgrid()函数解析
2021-05-10
java获取的NTLM电脑用户名并解码(python解码)
2021-05-10
Vue 中 hash 模式和 history 模式的区别
2021-05-10
运行 Webpack 项目图片和favicon.ico找不到, 图片404错误
2021-05-10