Java事务(六) - 使用注解改造

一. 前言:

上一篇文章中, 我们讲了使用动态代理完成事务处理, 这种方式将service层的所有public方法都加入事务中, 这显然不是我们需要的,我们需要代理的只是那些需要更改数据库的方法, 在本篇文章中,
我们将使用Java注解来标记需要处理事务的方法.

二. 实例:

1. 代码结构图:

2. 自定义注解:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Transactional{
}

3. 代理类:

/**
 * 动态代理
 */
public class TransactionProxy {

	public static Object proxyFor(Object object) {
		return Proxy.newProxyInstance(
										object.getClass().getClassLoader(),
										object.getClass().getInterfaces(),
										new TransactionInvocationHandler(object)
									 );
	}
}

class TransactionInvocationHandler implements InvocationHandler {
	private Object proxy;

	TransactionInvocationHandler(Object object) {
		this.proxy = object;
	}

	public Object invoke(Object obj, Method method, Object[] objects) throws Throwable {
		Method originalMethod = proxy.getClass().getMethod(method.getName(), method.getParameterTypes());
		// 判断方法上是否有Transactional注解
		if (!originalMethod.isAnnotationPresent(Transactional.class)) {
			// 没有注解, 直接调用方法不用控制事务
			return method.invoke(proxy, objects);
		}

		TransactionManager.beginTransaction();
		Object result = null;
		try {
			result = method.invoke(proxy, objects);
			TransactionManager.commit();
		} catch (Exception e) {
			TransactionManager.rollback();
		} finally {
			TransactionManager.close();
		}
		return result;
	}
}

在TransactionInvocationHandle的invoke方法中, 首先判断被代理的方法是否标记有Transactional注解,

如果没有则直接调用method.invoke(proxy, objects), 否则, 进入事务处理代码.

4. 业务代码类:

/**
 * 业务逻辑层
 */
public class AccountServiceImpl implements AccountService {

	@Override
	@Transactional
	public void transfer(Account outAccount, Account inAccount, int money) throws SQLException {
		// 查询两个账户
		AccountDAO accountDAO = new AccountDAO();
		outAccount = accountDAO.findAccountById(outAccount.getId());
		inAccount = accountDAO.findAccountById(inAccount.getId());

		// 转账 - 修改原账户金额
		outAccount.setMoney(outAccount.getMoney() - money);
		inAccount.setMoney(inAccount.getMoney() + money);

		// 更新账户金额
		accountDAO.update(outAccount);
		accountDAO.update(inAccount);
	}
}

在方法上标注使用注解.

参考文章:http://www.davenkin.me/post/2013-02-24/40048572306

源码下载: http://download.csdn.net/detail/zdp072/7908913

时间: 2024-10-28 20:44:09

Java事务(六) - 使用注解改造的相关文章

Java事务与JTA

一.什么是JAVA事务 通俗的理解,事务是一组原子操作单元,从数据库角度说,就是一组SQL指令,要么全部执行成功,若因为某个原因其中一条指令执行有错误,则撤销先前执行过的所有指令.更简答的说就是:要么全部执行成功,要么撤销不执行. 事务必须服从ISO/IEC所制定的ACID原则. 原子性(atomicity) 一致性(consistency) 隔离性(isolation) 持久性(durability) 原子性表示事务执行过程中的任何失败都将导致事务所做的任何修改失效. 一致性表示当事务执行失败

java之 ------ JUnit、注解、类加载器

JUnit软件测试技术(工具) 在项目中建立专门用户测试的包结构. 在Junit中,通过@Test注解,可以运行一个方法(鼠标放在选择要运行的方法名上,单击右键,选择Run As,再选择JUnit Test即可). 这样做的好处就是不用在主代码中添加测试代码,避免了代码的冗余.而且一个测试类,可以测试多项功能,不需要main方法. 一. Junit注解说明 使用了@Test注解应该满足以下条件: 1) 必须是无参数的非静态方法. 2) 添加@Test注解的类,必须拥有一个无参数的公开构造 pac

转载-Java事务与JTA

Java事务与JTA 一.什么是Java事务 通俗的理解,事务是事务是一组原子操作单元,从数据库角度说,就是一组SQL指令,要么全部执行成功,若因为某个原因其中一条指令执行有错误,则撤销先前执行过的所有指令.更简答的说就是:要么全部执行成功,要么撤销不执行. 事务必须服从ISO/IEC所制定的ACID原则. 原子性(atomicity) 一致性(consistency) 隔离性(isolation) 持久性(durability) 原子性表示事务执行过程中的任何失败都将导致事务所做的任何修改失效

Spring之事务操作(注解)

事务操作步骤: <!-- 第一步.配置事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <

Java复习——枚举与注解

枚举 枚举就是让某些变量的取值只能是若干固定值中的一个,否则编译器就会报错,枚举可以让编译器在编译阶段就控制程序的值,这一点是普通变量无法实现的.枚举是作为一种特殊的类存在的,使用的是enum关键字修饰 枚举常量 枚举常量默认都是使用static final修饰的,所以语法建议使用大写,一个枚举类在第一次被实例化的时候,这些常量就会被创建,这些常量都是枚举类子类的对象 public enum WeekDay{ //每一个枚举的元素(枚举常量)就是一个枚举类子类的对象,是使用static fina

Java解惑六:库之谜

本文是根据JAVA解惑这本书,做的笔记. 电子书见:http://download.csdn.net/detail/u010378705/7527721 谜题56 BigInteger.BigDecimal以及包装类型的实例是不可改变. BigInteger five = new BigInteger("5"); BigInteger total = BigInteger.ZERO; total.add(five); //这并不会改变total的值,调用该方法的返回值,才是加法得到的结

Java 8的类型注解:工具和机会

在以前的Java版本中,开发者只能将注解(Annotation)写在声明中.对于Java 8,注解可以写在使用类型的任何地方,例如声明.泛型和强制类型转换等语句: @Encrypted String data;List strings;myGraph = (@Immutable Graph) tmpGraph; 乍一看,类型注解并不是Java新版本最炫的特性.事实上,注解只是语法!工具决定了注解的的语义(即,它们的含义和行为).本文介绍新的注解语法和实用工具,以提高生产力和构建更高质量的软件.

【JAVA】六 JAVA Map 一 HashMap

[JAVA]六 JAVA Map 一 HashMap JDK API java.util Interface Map Type Parameters: K - the type of keys maintained by this map V - the type of mapped values All Known Subinterfaces: Bindings, ConcurrentMap<K,V>, ConcurrentNavigableMap<K,V>, LogicalMe

温故而知新java事务

一.什么是Java事务 通常的观念认为,事务仅与数据库相关. 事务必须服从ISO/IEC所制定的ACID原则.ACID是原子性(atomicity).一致性(consistency).隔离性 (isolation)和持久性(durability)的缩写. 原子性:表示事务执行过程中的任何失败都将导致事务所做的任何修改失效. 一致性:表示 当事务执行失败时,所有被该事务影响的数据都应该恢复到事务执行前的状态. 隔离性:表示在事务执行过程中对数据的修改,在事务提交之前对其他事务不可见. 持 久性:表