Spring Principle Transaction Analysis - part two

Spring Principle Transaction Analysis - part two

Description: This is what I learned some courses more than the teacher notes handwritten Spring Framework ants classroom, part of the code code code is used courseware more than the teacher. This is not advertising, I feel good after listening.

Classroom link: the Spring Framework handwriting

Handwritten Spring transaction framework

Programming transaction implementation

Outline

The so-called programmatic transaction refers achieved by encoding the transaction that is similar to JDBC programming transaction management. Management or directly using TransactionTemplate underlying PlatformTransactionManager. For programmatic transaction management, spring recommended TransactionTemplate.

Programming with manual transaction transaction implementation

Use affairs programming to achieve, manual transaction begin, commit, rollback

@Component
public class TransactionUtils {

	@Autowired
	private DataSourceTransactionManager dataSourceTransactionManager;

	// 开启事务
	public TransactionStatus begin() {
		TransactionStatus transaction = dataSourceTransactionManager.getTransaction(new DefaultTransactionAttribute());
		return transaction;
	}

	// 提交事务
	public void commit(TransactionStatus transactionStatus) {
		dataSourceTransactionManager.commit(transactionStatus);
	}

	// 回滚事务
	public void rollback(TransactionStatus transactionStatus) {
		dataSourceTransactionManager.rollback(transactionStatus);
	}
}

@Service
public class UserService {
	@Autowired
	private UserDao userDao;
	@Autowired
	private TransactionUtils transactionUtils;

	public void add() {
		TransactionStatus transactionStatus = null;
		try {
			transactionStatus = transactionUtils.begin();
			userDao.add("wangmazi", 27);
			int i = 1 / 0;
			System.out.println("我是add方法");
			userDao.add("zhangsan", 16);
			transactionUtils.commit(transactionStatus);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (transactionStatus != null) {
				transactionStatus.rollbackToSavepoint(transactionStatus);
			}
		}

	}

}

Manual transactions art package AOP

@Component
@Aspect
public class AopTransaction {
	@Autowired
	private TransactionUtils transactionUtils;

	// // 异常通知
	@AfterThrowing("execution(* com.itmayiedu.service.UserService.add(..))")
	public void afterThrowing() {
		System.out.println("程序已经回滚");
		// 获取程序当前事务 进行回滚
		TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
	}

	// 环绕通知
	@Around("execution(* com.itmayiedu.service.UserService.add(..))")
	public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
		System.out.println("开启事务");
		TransactionStatus begin = transactionUtils.begin();
		proceedingJoinPoint.proceed();
		transactionUtils.commit(begin);
		System.out.println("提交事务");
	}

}

Notes on using transactions

A transaction is running if there is no error, things will automatically be submitted if the program runs an exception occurs, it is automatically rolled back.

If you try to use the time to catch the exception. Be sure to manually rollback in the catch inside.

Manual rollback transaction codes

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

Statement transaction implementation

Outline

Management built on AOP. Its essence is to intercept method before and after, and then create or join a transaction before the target method begins, commit or roll back the transaction in accordance with the implementation after executing the target method. The biggest advantage is declarative transaction does not need to programmatically manage transactions, transaction management so you do not need doping code in the business logic code, just do the relevant business rules declared in the configuration file (or by @Transactional based notes the way), you can apply the rule to the transaction of business logic.

Declarative transaction management is clearly superior to programmatic transaction management, which is the spring non-invasive way of development advocated.

Declarative transaction management to make business code from pollution, a common POJO objects, as long as annotate can get full transaction support. And programmatic transaction compared declarative transaction where only downside is that the latter can only be applied to most fine-grained method level, you can not do as programmatic transaction that can be applied to the block level. But even if there is such a demand, there are many alternative methods, for example, can require transaction management code block is independent method and so on.

XML implementation declaration

An annotated version of the statement

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
    	 http://www.springframework.org/schema/beans/spring-beans.xsd
     	 http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd
         http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop.xsd
         http://www.springframework.org/schema/tx
     	 http://www.springframework.org/schema/tx/spring-tx.xsd">


	<!-- 开启注解 -->
	<context:component-scan base-package="com.itmayiedu"></context:component-scan>
	<!-- 1. 数据源对象: C3P0连接池 -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
		<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property>
		<property name="user" value="root"></property>
		<property name="password" value="root"></property>
	</bean>

	<!-- 2. JdbcTemplate工具类实例 -->
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource"></property>
	</bean>

	<!-- 配置事物 -->
	<bean id="dataSourceTransactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	<!-- 开启注解事物 -->
	<tx:annotation-driven transaction-manager="dataSourceTransactionManager" />
</beans>

usage

@Transactional
	public void add() {
		userDao.add("wangmazi", 27);
		int i = 1 / 0;
		System.out.println("我是add方法");
		userDao.add("zhangsan", 16);
	}

Spring handwritten notes version Affairs

annotation

Jdk1.5 add new technology, notes. Many frameworks to simplify the code, will provide some comments. Can be understood as plug-ins, is the code-level plug-in on class methods written: @XXX, a plug is inserted in the code.

Notes not and can not affect the actual logic of the code, only play a supplementary role.

Notes Category: Built-in annotation (also known as a meta-annotation jdk own notes), custom annotation (Spring Framework)

What is the built-in Notes

(1) @SuppressWarnings then be removed program preceded by a warning javac compilation - phase is the SOURCE
the SOURCE (2) @Deprecated marked packet, the method, which field specifies obsolete ---- stage
(3) @Overricle Applying this marker shows that the method is a method to rewrite the parent class - stage SOURCE

@Overricle case presentations
@Override
	public String toString() {
		return null;
	}

@Deprecated case presentations
	new Date().parse("");
@SuppressWarnings case presentations
@SuppressWarnings({ "all" })
	public void save() {
		java.util.List list = new ArrayList();
	}

Implement custom annotation

Meta-annotation role is responsible for other annotation notes. Java5.0 standard defines four meta-annotation type, which are used to provide other types of annotation specified. Yuan notes Java5.0 defined:
@Target

Annotation @Target illustrates the modified target range: Annotation may be used for packages, types (classes, interfaces, enumerations, Annotation type), a member type (method, constructor, member variables enumerated value), and the method parameters local variables (e.g., variable loop, catch parameters). Use a target in the Annotation type declaration can be more clear that it modifies the target.

. \ 1 CONSTRUCTOR: constructor is used to describe

. \ 2 FIELD: used to describe the field

\ 3 LOCAL_VARIABLE:. Local variables used to describe the

. \ 4 METHOD: The method described for

. \ 5 PACKAGE: Package for describing

. \ 6 PARAMETER: parameters used to describe the

\ 7 TYPE:. For describing class, interface (including type of annotation), or an enum declaration

2.@Retention

Comment information indicates the need to save at what level, annotations for describing the life cycle (i.e.: effective annotations are described in what extent)
3. 4. @ @ Inherited of Documented

@Interface defined using annotations.

@Target(value = { ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface AddAnnotation {

	int userId() default

t 0;

	String userName() default "默认名称";

	String[]arrays();
}
反射读取注解信息
	public static void main(String[] args) throws ClassNotFoundException {
		Class classInfo = Class.forName("com.itmayiedu.entity.User");
		// 获取到所有方法
		Method[] methods = classInfo.getDeclaredMethods();
		for (Method method : methods) {
			System.out.println(method);
			AddAnnotation declaredAnnotation = method.getDeclaredAnnotation(AddAnnotation.class);
			if (declaredAnnotation == null) {
				// 结束本次循环
				continue;
			}
			// 获取userId
			int userId = declaredAnnotation.userId();
			System.out.println("userId:" + userId);
			// 获取userName
			String userName = declaredAnnotation.userName();
			System.out.println("userName:" + userName);
			// 获取arrays
			String[] arrays = declaredAnnotation.arrays();
			for (String str : arrays) {
				System.out.println("str:" + str);
			}
		}
	}



Custom Affairs notes

//编程事务(需要手动begin 手动回滚  手都提交)
@Component()
@Scope("prototype") // 设置成原型解决线程安全
public class TransactionUtils {

	private TransactionStatus transactionStatus;
	// 获取事务源
	@Autowired
	private DataSourceTransactionManager dataSourceTransactionManager;

	// 开启事务
	public TransactionStatus begin() {
		transactionStatus = dataSourceTransactionManager.getTransaction(new DefaultTransactionAttribute());
		return transactionStatus;
	}

	// 提交事务
	public void commit(TransactionStatus transaction) {
		dataSourceTransactionManager.commit(transaction);
	}

	// 回滚事务
	public void rollback() {
		System.out.println("rollback");
		dataSourceTransactionManager.rollback(transactionStatus);
	}

}

注解类

@Autowired
	private TransactionUtils transactionUtils;

	@AfterThrowing("execution(* com.itmayiedu.service.*.*.*(..))")
	public void afterThrowing() throws NoSuchMethodException, SecurityException {
		// isRollback(proceedingJoinPoint);
		System.out.println("程序发生异常");
		// TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
		// TransactionStatus currentTransactionStatus =
		// TransactionAspectSupport.currentTransactionStatus();
		// System.out.println("currentTransactionStatus:" +
		// currentTransactionStatus);
		transactionUtils.rollback();
	}

	// // 环绕通知 在方法之前和之后处理事情
	@Around("execution(* com.itmayiedu.service.*.*.*(..))")
	public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

		// 调用方法之前执行
		TransactionStatus transactionStatus = begin(proceedingJoinPoint);
		proceedingJoinPoint.proceed();// 代理调用方法 注意点: 如果调用方法抛出异常不会执行后面代码
		// 调用方法之后执行
		commit(transactionStatus);
	}

	public TransactionStatus begin(ProceedingJoinPoint pjp) throws NoSuchMethodException, SecurityException {

		// // 判断是否有自定义事务注解
		ExtTransaction declaredAnnotation = getExtTransaction(pjp);
		if (declaredAnnotation == null) {
			return null;
		}
		// 如果有自定义事务注解,开启事务
		System.out.println("开启事务");
		TransactionStatus transactionStatu = transactionUtils.begin();
		return transactionStatu;
	}

	public void commit(TransactionStatus transactionStatu) {
		if (transactionStatu != null) {
			// 提交事务
			System.out.println("提交事务");
			transactionUtils.commit(transactionStatu);
		}
	}

	public ExtTransaction getExtTransaction(ProceedingJoinPoint pjp) throws NoSuchMethodException, SecurityException {
		// 获取方法名称
		String methodName = pjp.getSignature().getName();
		// 获取目标对象
		Class<?> classTarget = pjp.getTarget().getClass();
		// 获取目标对象类型
		Class<?>[] par = ((MethodSignature) pjp.getSignature()).getParameterTypes();
		// 获取目标对象方法
		Method objMethod = classTarget.getMethod(methodName, par);
		// // 判断是否有自定义事务注解
		ExtTransaction declaredAnnotation = objMethod.getDeclaredAnnotation(ExtTransaction.class);
		if (declaredAnnotation == null) {
			System.out.println("您的方法上,没有加入注解!");
			return null;
		}
		return declaredAnnotation;

	}

	// 回滚事务
	public void isRollback(ProceedingJoinPoint pjp) throws NoSuchMethodException, SecurityException {
		// // 判断是否有自定义事务注解
		ExtTransaction declaredAnnotation = getExtTransaction(pjp);
		if (declaredAnnotation != null) {
			System.out.println("已经开始回滚事务");
			// 获取当前事务 直接回滚
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return;
		}
	}

使用自定义注解

@ExtTransaction
public void add() {
userDao.add("test001", 20);
int i = 1 / 0;
System.out.println("################");
userDao.add("test002", 21);
}


Guess you like

Origin blog.csdn.net/weixin_40160543/article/details/92250037