《Java》-------用AOP思想实现JDBC事物的管理

    当我们读数据库进行操作的时候,有些时候“事物的管理”是避免不了的。从事物的开启,提交、回滚的基本操作来说,还有包括在这些操作之间的逻辑代码,我们必须保证这些链接数据库对象的Connection是同一个。只有这样我们才能保证事物的完整性。还有,当我们管理事物时,我们需要将管理事物的操作封装成一个动态代理类,这样一来,我们可以很容易将事物的管理嵌套在业务逻辑中。

   1、保证数据库链接对象一致的问题:我们可以用ThreadLocal对象存放当前线程的Connection对象,这样不但保证了其它线程读取不到此线程内的Connection对象,当我们获取Connection对象时,还能保证是同一个。下面是具体的代码。

public class TransationManager {
	private static ThreadLocal<Connection> t1 = new ThreadLocal<Connection>();

	public static Connection getConnection() {
		Connection conn = t1.get();
		if (conn == null) {
			conn = DBCPUtil.getConnection();
			t1.set(conn);// 将连接绑在当前线程上
		}
		return conn;
	}

	// 开启事物
	public static void startTransaction() {
		Connection conn = getConnection();
		try {
			conn.setAutoCommit(false);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	// 提交事物
	public static void commit() {
		Connection conn = getConnection();
		try {
			conn.commit();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	// 回滚事物
	public static void rollback() {
		Connection conn = getConnection();
		try {
			conn.rollback();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	// 释放资源
	public static void release() {
		Connection conn = getConnection();
		try {
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}
    2、利用动态代理封装一个BeanFactory,当我们需要管理事物时,就生成代理对象,让代理对象帮我们实现,这里还体现了面向切面编程的思想(AOP),当我们不需要事物的一些操作时,我们可以生成具体的业务逻辑对象。代码如下。

public class BeanFactory {
	public static BusinessService getBusinessService(boolean isProxy) {
		final BusinessService s = new BusinessServiceImpl();
		if (isProxy) {
			// 返回代理实现类
			BusinessService proxyS = (BusinessService) Proxy.newProxyInstance(s
					.getClass().getClassLoader(), s.getClass().getInterfaces(),
					new InvocationHandler() {
						@Override
						public Object invoke(Object proxy, Method method,
								Object[] args) throws Throwable {
							Object rtValue = null;

							try {
								TransationManager.startTransaction();// 开启事物
								rtValue = method.invoke(s, args); // 此处是我的代理的方法
								TransationManager.commit(); // 提交事物
							} catch (Exception e) {
								TransationManager.rollback(); // 回滚事物
								throw new RuntimeException(e);
							} finally {
								TransationManager.release(); // 释放资源
							}
							return rtValue;
						}
					});
			return proxyS;
		} else {
			return s;
		}
	}
}

    3、当我们用commons-dbutils-1.4.jar包管理我们的JDBC操作时,我们不要忘了往QueryRunner对象的CRUD方法中传入Connection对象。这里小编用D层的一段查询和更新代码举例。
public class AccountDaoImpl implements AccountDao {
	private QueryRunner qr = new QueryRunner();
	// 查询操作
	public Account findAccountByName(String accountName) {
		try {
			return qr.query(TransationManager.getConnection(),
					"select * from account where name=?",
					new BeanHandler<Account>(Account.class), accountName);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

	// 更新操作
	public void updateAccount(Account account) {
		try {
			qr.update(TransationManager.getConnection(),
					"update account set money=? where id=?",
					account.getMoney(), account.getId());
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
}

    利用动态代理实现事物的统一管理确实能提高开发效率,面向切面编程的思想的核心就是动态代理,其实AOP的思想还可以用在日志管理,执行性能监控的功能,这里小编只是抛砖引玉,将小小的动态代理介绍一下。以后肯定会继续进攻这些高大上的技术。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 15
    评论
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值