作者|结森
public ConfirmOrderResultVO batchConfirmPurchaseOrders(Long taobaoUserId, List<String> bizOrderIds) throws TCException {
………………………………………………………………
for (String bizOrderId : bizOrderIds) {
// 推单成功进入successList,否则进入failedList
if (confirmPurchaseOrder(taobaoUserId, bizOrderId)){
successList.add(Long.valueOf(bizOrderId));
}else {
failedList.add(Long.valueOf(bizOrderId));
}
}
………………………………………………………………
}
@Transactional
public Boolean confirmPurchaseOrder(Long taobaoUserId, String bizOrderId) throws TCException {
logger.warn("|ConfirmPurchaseOrder|UserId:"+taobaoUserId+",orderId:"+bizOrderId);
…………………………
return ture;
}
public interface Homework {
void doHomework();
}
public class XiaoHong implements Homework{
@Override
public void doHomework() {
System.out.println("XiaoHong did homework casually");
}
}
public class XiaoWang implements Homework{
// 持有Homework属性
private Homework homework;
// 通过构造函数初始化Homework
public XiaoWang(Homework homework){
this.homework=homework;
}
//代理实现
@Override
public void doHomework() {
doStudy();
homework.doHomework();
System.out.println("XiaoWang helps with MathHomework");
doCheck();
}
// 额外方法
private void doCheck() {
System.out.println("XiaoWang is checking-----------------");
}
// 额外方法
private void doStudy() {
System.out.println("XiaoWang is studying---------------");
}
}
public class XiaoZhang implements Homework{
// 持有Homework属性
private Homework homework;
// 通过构造函数初始化Homework
public XiaoZhang(Homework homework){
this.homework=homework;
}
//代理实现
@Override
public void doHomework() {
doStudy();
homework.doHomework();
System.out.println("XiaoZhang helps with EngHomework");
doCheck();
}
// 额外方法
private void doCheck() {
System.out.println("XiaoZhang is checking-----------------");
}
// 额外方法
private void doStudy() {
System.out.println("XiaoZhang is studying---------------");
}
}
public static void main(String[] args) {
// 实例化一个目标对象
XiaoHong xiaoHong = new XiaoHong();
// 把目标对象通过构造函数传递给代理对象
XiaoZhang xiaoZhang =new XiaoZhang(xiaoHong);
XiaoWang xiaoWang =new XiaoWang(xiaoHong);
// 调用代理对象的方法
xiaoZhang.doHomework();
xiaoWang.doHomework();
}
XiaoZhang is studying---------------
XiaoHong did homework casually
XiaoZhang helps with EngHomework
XiaoZhang is checking-----------------
XiaoWang is studying---------------
XiaoHong did homework casually
XiaoWang helps with MathHomework
XiaoWang is checking-----------------
动态代理
JDK实现动态代理
// 实现InvocationHandler
public class RobotProxy implements InvocationHandler {
// 持有一个Object类型的目标对象target
private Object target;
// 通过构造函数实例化目标对象target
public RobotProxy(Object target) {
this.target = target;
}
// 重写invoke方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
doStudy();
// 执行目标对象的方法
Object invoke = method.invoke(target, args);
doCheck();
return invoke;
}
// 额外动作
private void doStudy() {
System.out.println("Robot is studying------------");
}
// 额外动作
private void doCheck() {
System.out.println("Robot is checking------------");
}
}
public static void main(String[] args) {
// 实例化一个目标对象
XiaoHong xiaoHong = new XiaoHong();
// 传入实现的接口 new Class[]{Homework.class}
// 以及代理类 new RobotProxy(xiaoHong)
Homework homework = (Homework)Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Homework.class}, new RobotProxy(xiaoHong));
homework.doHomework();
}
Robot is studying------------
XiaoHong did homework casually
Robot is checking------------
Cglib实现动态代理
// 实现MethodInterceptor方法(要引入cglib包)
public class RobotV2Proxy implements MethodInterceptor {
// 重写intercept方法
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
doStudy();
Object invoke = methodProxy.invokeSuper(o, objects);
doCheck();
return invoke;
}
// 额外动作
private void doStudy() {
System.out.println("RobotV2 is studying------------");
}
// 额外动作
private void doCheck() {
System.out.println("RobotV2 is checking------------");
}
}
public static void main(String[] args) {
// 创建增强类
Enhancer enhancer = new Enhancer();
// 设置父类
enhancer.setSuperclass(XiaoHong.class);
// 设置回调
enhancer.setCallback(new RobotV2Proxy());
// 创建目标对象
XiaoHong xiaoHong = (XiaoHong)enhancer.create();
// 调用目标方法
xiaoHong.doHomework();
}
RobotV2 is studying------------
XiaoHong did homework casually
RobotV2 is checking------------
-
基于字节码,生成真实对象的子类。 -
运行效率高于JDK代理 -
不需要实现接口
注解型事务
注解型事务使用
事务执行原理
PlatformTransactionManager
public interface PlatformTransactionManager extends TransactionManager {
/**
* 获取事务
/*
TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException;
/**
* 提交事务
/*
void commit(TransactionStatus status) throws TransactionException;
/**
* 回滚事务
/*
void rollback(TransactionStatus status) throws TransactionException;
}
@Override
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
throws TransactionException {
// 获取事务定义(该类保存了当前事务的相关属性,例如传播规则、隔离规则等)
TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());
// 获取真正的事务(doGetTransaction方法由具体的持久层框架实现)
Object transaction = doGetTransaction();
boolean debugEnabled = logger.isDebugEnabled();
// 如果已经存在事务,则根据传播规则执行相应的处理
if (isExistingTransaction(transaction)) {
return handleExistingTransaction(def, transaction, debugEnabled);
}
// 检查当前事务的超时时间
if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
throw new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout());
}
// 如果当前不存在事务,检查传播级别和隔离级别,开始执行事务 startTransaction()
if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
throw new IllegalTransactionStateException(
"No existing transaction found for transaction marked with propagation 'mandatory'");
}
else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
SuspendedResourcesHolder suspendedResources = suspend(null);
if (debugEnabled) {
logger.debug("Creating new transaction with name [" + def.getName() + "]: " + def);
}
try {
return startTransaction(def, transaction, debugEnabled, suspendedResources);
}
catch (RuntimeException | Error ex) {
resume(null, suspendedResources);
throw ex;
}
}
else {
// Create "empty" transaction: no actual transaction, but potentially synchronization.
if (def.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
logger.warn("Custom isolation level specified but no actual transaction initiated; " +
"isolation level will effectively be ignored: " + def);
}
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);
}
}
public final void commit(TransactionStatus status) throws TransactionException {
// 如果当前事务已经完成,抛出异常
if (status.isCompleted()) {
throw new IllegalTransactionStateException(
"Transaction is already completed - do not call commit or rollback more than once per transaction");
}
DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
// 如果当前事务设置了回滚标识,则进行回滚操作
if (defStatus.isLocalRollbackOnly()) {
if (defStatus.isDebug()) {
logger.debug("Transactional code has requested rollback");
}
processRollback(defStatus, false);
return;
}
// 如果全局事务设置了回滚标识,则进行回滚操作(也就是事务嵌套的场景)
if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
if (defStatus.isDebug()) {
logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
}
processRollback(defStatus, true);
return;
}
// 提交事务
processCommit(defStatus);
}
public final void rollback(TransactionStatus status) throws TransactionException {
// 如果当前事务已经完成,抛出异常
if (status.isCompleted()) {
throw new IllegalTransactionStateException(
"Transaction is already completed - do not call commit or rollback more than once per transaction");
}
DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
processRollback(defStatus, false);
}
private void processRollback(DefaultTransactionStatus status, boolean unexpected) {
try {
boolean unexpectedRollback = unexpected;
try {
triggerBeforeCompletion(status);
// 如果当前事务存在保存点,则回滚到保存点的状态
if (status.hasSavepoint()) {
if (status.isDebug()) {
logger.debug("Rolling back transaction to savepoint");
}
status.rollbackToHeldSavepoint();
}
// 如果是新的事务,则执行doRollback方法
else if (status.isNewTransaction()) {
if (status.isDebug()) {
logger.debug("Initiating transaction rollback");
}
doRollback(status);
}
else {
// 如果有嵌套事务,则执行doSetRollbackOnly方法
if (status.hasTransaction()) {
if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {
if (status.isDebug()) {
logger.debug("Participating transaction failed - marking existing transaction as rollback-only");
}
doSetRollbackOnly(status);
}
else {
if (status.isDebug()) {
logger.debug("Participating transaction failed - letting transaction originator decide on rollback");
}
}
}
else {
logger.debug("Should roll back transaction but cannot - no transaction available");
}
// Unexpected rollback only matters here if we're asked to fail early
if (!isFailEarlyOnGlobalRollbackOnly()) {
unexpectedRollback = false;
}
}
}
catch (RuntimeException | Error ex) {
triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
throw ex;
}
triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
// Raise UnexpectedRollbackException if we had a global rollback-only marker
// 发生了不期望的回滚异常
if (unexpectedRollback) {
throw new UnexpectedRollbackException(
"Transaction rolled back because it has been marked as rollback-only");
}
}
finally {
cleanupAfterCompletion(status);
}
}
DynamicAdvisedInterceptor
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
private final AdvisedSupport advised;
public DynamicAdvisedInterceptor(AdvisedSupport advised) {
this.advised = advised;
}
@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.getTargetSource();
try {
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// Check whether we only have one InvokerInterceptor: that is,
// no real advice, but just reflective invocation of the target.
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
// We can skip creating a MethodInvocation: just invoke the target directly.
// Note that the final invoker must be an InvokerInterceptor, so we know
// it does nothing but a reflective operation on the target, and no hot
// swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}
else {
// We need to create a method invocation...
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass)
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
TransactionInterceptor
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {
@Nullable
public Object invoke(final MethodInvocation invocation) throws Throwable {
// 获取目标类
Class<?> targetClass = invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null;
// 执行事务方法
return this.invokeWithinTransaction(invocation.getMethod(), targetClass, new CoroutinesInvocationCallback() {
@Nullable
public Object proceedWithInvocation() throws Throwable {
return invocation.proceed();
}
public Object getTarget() {
return invocation.getThis();
}
public Object[] getArguments() {
return invocation.getArguments();
}
});
}
}
invokeWithinTransaction
@Nullable
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
// If the transaction attribute is null, the method is non-transactional.
TransactionAttributeSource tas = getTransactionAttributeSource();
// 获取事务属性类TransactionAttribute
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
// 根据事务属性选择合适的事务管理器(如PlatformTransactionManager)
final TransactionManager tm = determineTransactionManager(txAttr);
………………………………………………………………………………
}
getTransactionAttribute
public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
if (method.getDeclaringClass() == Object.class) {
return null;
}
// 从缓存中获取TransactionAttribute
Object cacheKey = getCacheKey(method, targetClass);
TransactionAttribute cached = this.attributeCache.get(cacheKey);
if (cached != null) {
// Value will either be canonical value indicating there is no transaction attribute,
// or an actual transaction attribute.
if (cached == NULL_TRANSACTION_ATTRIBUTE) {
return null;
}
else {
return cached;
}
}
else {
// 如果缓存中没有TransactionAttribute,则构建一个新的TransactionAttribute
TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
// Put it in the cache.
if (txAttr == null) {
this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
}
………………………………………………………………………………
}
protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
// 校验当前注解的方法是否是public的(也就是@Transactional注解的方法必须是public的)
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}
// 获取真实目标对象的方法(获取代理对象真正代理的目标对象的执行方法)
Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
// 从目标对象的方法中获取事务属性(其实就是在找注解,先找方法上有没有注解)
TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
if (txAttr != null) {
return txAttr;
}
// 从目标对象的类中获取事务属性(再找类上有没有注解)
txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
if (specificMethod != method) {
// Fallback is to look at the original method.
txAttr = findTransactionAttribute(method);
if (txAttr != null) {
return txAttr;
}
// Last fallback is the class of the original method.
txAttr = findTransactionAttribute(method.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
}
return null;
}
invokeWithinTransaction
PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
// Standard transaction demarcation with getTransaction and commit/rollback calls.
TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
Object retVal;
try {
// 动态代理调用目标对象本身的数据库操作
// This is an around advice: Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// 如果发生异常要进行回滚(内部是获取相应的TransactionManager,执行rollback方法)
// target invocation exception
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
// 释放事务资源
cleanupTransactionInfo(txInfo);
}
if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
// Set rollback-only in case of Vavr failure matching our rollback rules...
TransactionStatus status = txInfo.getTransactionStatus();
if (status != null && txAttr != null) {
retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
}
}
// 提交事务(内部是获取相应的TransactionManager,执行commit方法)
commitTransactionAfterReturning(txInfo);
return retVal;
}

