Transactional Async from mistakes and to use dynamic proxies

Speaking from Transactional and Async comment

When you need to turn a method for asynchronous thread, at the same time open affairs, novice to use Spring's most of them will make a mistake, will @Transactionalthe @Asynccombination. A direct consequence of such use is Mingming Jia a @Transactionalcomment why the transaction could not be executed successfully.

The reason is simple:

  1. Spring accomplish this is by way of two notes AOP.
  2. When implementing, Async notes mandatory coverage AOPof order to a minimum (Async think it should be performed AOPfirst advisor chain - jira.spring.io/browse/SPR-...
  3. However, when implementing Transactional annotation, but does not cover the order, which means it is still the default Integer.MAX_VALUE, order can be configured. So asynchronous section will first perform in the transaction section.
  4. Assumptions @Transactionalcan precede Async section executed, but due to spring transaction management relies ThreadLocal, so in the open asynchronous threads inside imperceptible affairs, said fine point is open after a transaction in Spring, will set up a connection to the current thread, but this time has opened a new thread when performing the actual SQL code, will open a new connection through ThreadLocal not get connected, it will not set autoCommit, so this function will no overall transaction.

Dynamic Proxy

Agent is dynamically acquired proxy object type to be reflected by the bytecode manipulation mechanism or the like technique to dynamically, so as to obtain the relevant characteristics of the agent. AOP is the dynamic agent of a specific form.

Because in the development process encountered before, so take the above example to be opening at that time in order to solve this error, in which the principles of understanding, so to delve into a lot.

Spring dynamic proxy implemented in two ways, JDK and Cglib.

Here not to explore the deep-seated source, but so that we can flexibly using dynamic proxy important technology in this door different development scenarios.

  • There is one caveat:
    1. JDK agent to achieve the prerequisite is that the proxied class must implement the interface, because our agency when it is inherited from the interface and then construct according to the proxy class. The Cglib is no such requirement.
    2. cglib is for the class to implement a proxy, the principle is to generate a subclass of the specified class to be the agent, and which covered methods for enhanced, but because the use of inheritance, it can not be modified on the final proxy class.

Suppose there is an interface TestP its implementation class TestPImpl

JDK dynamic proxy implementation

/**
  *JDK代理的实现前提是被代理的类,必须实现了接口,因为我们代理的时候,
  *正是根据继承自接口然后构造的代理类。
*/
public class JdkProxy implements InvocationHandler{
 
	private Object target;
    /** 
     * 绑定需要被代理的对象
     * 返回代理类 
     */  
    public Object bind(Object target) {
        this.target = target;  
        //取得代理对象  
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),  
                target.getClass().getInterfaces(), this);  
    }  
  
    @Override  
    public Object invoke(Object proxy, Method method, Object[] args)  
            throws Throwable {  
        Object result=null;  
        System.out.println("代理开始");  
        //你的方法
        result=method.invoke(target, args);  
        System.out.println("代理结束");  
        return result;  
    }  
}

public class TestJdkProxy {
 
	public static void main(String[] args) {
		JdkProxy jp = new JdkProxy();
		TestP tp = (TestP)jp .bind(new TestPImpl());
		tp.someMethod();
	}
	
}
复制代码

Cglib dynamic proxy implementation

public class CglibProxy implements MethodInterceptor {
 
	private Object target;
 
	public Object getInstance(Object target) {
		this.target = target;
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(this.target.getClass());
		// 设置回调方法  
		enhancer.setCallback(this);
		// 创建代理对象  
		return enhancer.create();
	}
 
	@Override
	// 回调方法  
	public Object intercept(Object obj, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {
		System.out.println("代理开始");
        //你的方法
		proxy.invokeSuper(obj, args);
		System.out.println("代理开始");
		return null;
 
	}
 
}

public class TestCglibProxy {
 
	public static void main(String[] args) {
		
		CglibProxy cp= new CglibProxy();
		TestP  tp = (TestP)cp.getInstance(new TestPImpl()); 
		tp.someMethod();
	}
	
}
复制代码

Guess you like

Origin juejin.im/post/5d6a0675f265da03951a0ab3