Android10 客户端事务管理ClientLifecycleManager源码解析

目录
  • 正文
  • ClientLifecycleManager
  • ClientTransaction
  • TransactionExecutor
  • executeLifecycleState

正文

在Android 10 App启动分析之Activity启动篇(二)一文中,简单地介绍了Activity的生命周期管理器是如何调度Activity进入onCreate生命周期的流程。这篇文章,我们将详细地分析framework中activity的生命周期管理功能,从更宏观的角度来更全面地了解生命周期及相关事务的工作原理。

生命周期管理是google在Android 9才引入的设计,在Android 9之前,activity 存在生命周期的概念,但并无生命周期管理这一说法。为了方便生命周期的切换以及相关业务的管理,google采用了事务的思想,将生命周期抽象为客户端事务的一部分来统一管理。下图是客户端事务管理完整的UML图:

相关类说明:

  • ClientLifecycleManager: 客户端事务管理类,包括且不限于处理Activity生命周期转换事务,同时也包括 与客户端相关的其他事务处理。
  • ClientTransaction:事务集类,一个事务集可以存放一系列Callback事务及一个生命周期事务。
  • TransactionExecutor:事务执行器,让事务以正确的顺序执行。
  • BaseClientRequest :事务的抽象类,定义了preExecuteexecutepostExecute三个接口,分别代表事务执行前、执行中、执行后三个阶段的回调方法。
  • ActivityLifecycleItem:abstract class,Activity生命周期事务类,其子类有DestroyActivityItemPauseActivityItemStopActivityItemResumeActivityItem,表示具体的activity生命周期转换事务。
  • ClientTransactionItem:abstract class,客户端事务类,ActivityLifecycleItem是它的子类之一。除此之外,还有如下内置的客户端事务:
Transaction Name Desc
ConfigurationChangeItem App configuration 改变的消息
WindowVisibilityItem Window可见性发生改变的消息
MoveToDisplayItem Activity 移动到不同的显示设备的消息
MultiWindowModeChangeItem 多窗口模式改变的消息
ActivityConfigurationChangeItem Activity configuration 改变的回调
PipModeChangeItem 画中画模式改变的消息
ActivityResultItem Activity result的回调
NewIntentItem New intent消息
TopResumedActivityChangeItem Top resumed activity 改变的回调
ActivityRelaunchItem 重启Activity的回调
LaunchActivityItem 请求启动一个Activity

ClientLifecycleManager

ClientLifecycleManagerActivityTaskManagerService中初始化了唯一的实例,所有的事务操作,必须通过ATMS中的实例来发起。如: mService.getLifecycleManager().scheduleTransaction(clientTransaction);

ClientLifecycleManager的源码如下:

class ClientLifecycleManager {
    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();
        transaction.schedule();
        if (!(client instanceof Binder)) {
            // If client is not an instance of Binder - it's a remote call and at this point it is
            // safe to recycle the object. All objects used for local calls will be recycled after
            // the transaction is executed on client in ActivityThread.
            transaction.recycle();
        }
    }
    void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,
            @NonNull ActivityLifecycleItem stateRequest) throws RemoteException {
        final ClientTransaction clientTransaction = transactionWithState(client, activityToken,
                stateRequest);
        scheduleTransaction(clientTransaction);
    }
    void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,
            @NonNull ClientTransactionItem callback) throws RemoteException {
        final ClientTransaction clientTransaction = transactionWithCallback(client, activityToken,
                callback);
        scheduleTransaction(clientTransaction);
    }
    void scheduleTransaction(@NonNull IApplicationThread client,
            @NonNull ClientTransactionItem callback) throws RemoteException {
        final ClientTransaction clientTransaction = transactionWithCallback(client,
                null /* activityToken */, callback);
        scheduleTransaction(clientTransaction);
    }
    private static ClientTransaction transactionWithState(@NonNull IApplicationThread client,
            @NonNull IBinder activityToken, @NonNull ActivityLifecycleItem stateRequest) {
        final ClientTransaction clientTransaction = ClientTransaction.obtain(client, activityToken);
        clientTransaction.setLifecycleStateRequest(stateRequest);
        return clientTransaction;
    }
    private static ClientTransaction transactionWithCallback(@NonNull IApplicationThread client,
            IBinder activityToken, @NonNull ClientTransactionItem callback) {
        final ClientTransaction clientTransaction = ClientTransaction.obtain(client, activityToken);
        clientTransaction.addCallback(callback);
        return clientTransaction;
    }
}

可以看到,ClientLifecycleManager对外暴露了三种事务调度方法:一是 直接调度一个事务集(ClientTransaction);二是调度一个 Lifecycle事务; 三是调用一个Callback事务(ps:除LifeCycle以外的事务,都属于Callback事务)。实际上,无论是Lifecycle事务还是Callback事务,它们都被封装成了事务集的形式,并通过ClientTransaction中的schedule方法去进一步处理。

ClientTransaction

ClientTransaction里的schedule方法非常简单,代码如下所示:

    public void schedule() throws RemoteException {
        mClient.scheduleTransaction(this);
    }

上述代码片段中的mClient到底指的是什么?

从源码的角度来看,mClient 是 ApplicationThread的一个实例。而 ApplicationThread 是ActivityThread的一个内部类,作为ActivityThread 与外部沟通的桥梁。所有的事务集最终都会被派发到ActivityThread中统一处理。

ActivityThread.java
   void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }

ActivityThread里首先调用了ClientTransaction中的preExecute方法,代码片段如下:

    public void preExecute(android.app.ClientTransactionHandler clientTransactionHandler) {
        if (mActivityCallbacks != null) {
            final int size = mActivityCallbacks.size();
            for (int i = 0; i < size; ++i) {
                mActivityCallbacks.get(i).preExecute(clientTransactionHandler, mActivityToken);
            }
        }
        if (mLifecycleStateRequest != null) {
            mLifecycleStateRequest.preExecute(clientTransactionHandler, mActivityToken);
        }
    }

可以看到,ClientTransaction先调用了 所有注册的Callback事务的preExecute方法,然后调用了唯一的LifeCycle事务的preExecute方法。

在完成所有事务的preExecute逻辑后,ActivityThread发送了一条ActivityThread.H.EXECUTE_TRANSACTION的message,内容如下:

   mTransactionExecutor.execute(transaction);
   if (isSystem()) {
      transaction.recycle();
   }

接下来由TransactionExecutor负责后续的逻辑处理。

TransactionExecutor

 public void execute(ClientTransaction transaction) {
        final IBinder token = transaction.getActivityToken();
        if (token != null) {
            final Map<IBinder, ClientTransactionItem> activitiesToBeDestroyed =
                    mTransactionHandler.getActivitiesToBeDestroyed();
            final ClientTransactionItem destroyItem = activitiesToBeDestroyed.get(token);
            if (destroyItem != null) {
                if (transaction.getLifecycleStateRequest() == destroyItem) {
                    // It is going to execute the transaction that will destroy activity with the
                    // token, so the corresponding to-be-destroyed record can be removed.
                    activitiesToBeDestroyed.remove(token);
                }
                if (mTransactionHandler.getActivityClient(token) == null) {
                    // The activity has not been created but has been requested to destroy, so all
                    // transactions for the token are just like being cancelled.
                    Slog.w(TAG, tId(transaction) + "Skip pre-destroyed transaction:\n"
                            + transactionToString(transaction, mTransactionHandler));
                    return;
                }
            }
        }
        executeCallbacks(transaction);
        executeLifecycleState(transaction);
        mPendingActions.clear();
    }

execute中有一段对DestroyActivityItem特殊处理的逻辑,不太重要,我们忽略它。

我们分别来看一下executeCallbacksexecuteLifecycleState两个方法。

 public void executeCallbacks(ClientTransaction transaction) {
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
        if (callbacks == null || callbacks.isEmpty()) {
            return;
        }
        final IBinder token = transaction.getActivityToken();
        ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
        // In case when post-execution state of the last callback matches the final state requested
        // for the activity in this transaction, we won't do the last transition here and do it when
        // moving to final state instead (because it may contain additional parameters from server).
        final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();
        final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState()
                : UNDEFINED;
        // Index of the last callback that requests some post-execution state.
        final int lastCallbackRequestingState = lastCallbackRequestingState(transaction);
        final int size = callbacks.size();
        for (int i = 0; i < size; ++i) {
            final ClientTransactionItem item = callbacks.get(i);
            if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item);
            final int postExecutionState = item.getPostExecutionState();
            final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
                    item.getPostExecutionState());
            if (closestPreExecutionState != UNDEFINED) {
                cycleToPath(r, closestPreExecutionState, transaction);
            }
            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);
            if (r == null) {
                // Launch activity request will create an activity record.
                r = mTransactionHandler.getActivityClient(token);
            }
            if (postExecutionState != UNDEFINED && r != null) {
                // Skip the very last transition and perform it by explicit state request instead.
                final boolean shouldExcludeLastTransition =
                        i == lastCallbackRequestingState && finalState == postExecutionState;
                cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);
            }
        }
    }

上述代码主要做了以下几件事:

  • 获取事务集的target lifecycle。
  • 获取事务集中最后一次Activity生命周期转换的Callback索引。
  • 遍历所有的Callback事务。
  • 获取Callback事务的结束状态值,如结束状态值为onResume,检查Activity当前状态,判断当前的就近状态(onStart/onPause),并将activity转换到就近状态。
  • 执行Callback事务的execute和postExecute逻辑。
  • 跳过最后一个状态转换,改为通过显式状态变换去执行。

google这段逻辑写的极为繁杂啰嗦,让人吐槽的点实在太多了,但还是要在此讲一下它是怎么设计的,源码中又哪里糟点。

首先是事务集的target lifecycle,它指的是事务集中唯一的Lifecycle事务(如果存在的话)的状态,表示事务集执行完毕后,Activity最终的生命周期状态。

第二点,事务集中最后一次Activity生命周期转换的Callback索引,这句话是什么含义呢?

Callback事务中有这么一个方法,getPostExecutionState,它表示在当前Callback事务执行完毕后Activity所需处于的生命周期状态,为方便叙述,下文称其为结束状态。将Callback事务列表从后向前遍历,如果当前事务存在结束状态(即getPostExecutionState的值不为UNDEFINED),且与上一个结束状态相同,记录下此时事务在列表中的索引值,直到当前结束状态与上一个状态不同为止。此时,上一个事务的索引值即为事务集中最后一次Activity生命周期转换的Callback索引

假如某事务集有这样一组Callback事务——ConfigurationChangeItem、NewIntentItem、ConfigurationChangeItem、NewIntentItem。其中ConfigurationChangeItem的结束状态为UNDEFINED,NewIntentItem的结束状态为ON_RESUME。

我们从后向前开始遍历:

  • 最后一个事务为 NewIntentItem,结束状态为ON_RESUME,记录下此时的索引值 3。
  • 倒数第二个事务为 ConfigurationChangeItem,不存在结束状态,跳过。
  • 倒数第三个事务为 NewIntentItem,结束状态为ON_RESUME,上一个结束状态同样也是 ON_RESUME,更新索引值 为 1。
  • 倒数第四个事务为 ConfigurationChangeItem,不存在结束状态,跳过。

因此,此事务集中最后一次Activity生命周期转换的Callback索引 为1。至于这个索引值有什么意义呢,待会再解释。

然而,这段设计中还是有几点需要吐槽一下:

  • google官方在注释中举例的 事务是 Configuration - ActivityResult - Configuration - ActivityResult , 并且说明ActivityResult 的结束状态为RESUMED。让我们看看ActivityResultItem的源码:
public class ActivityResultItem extends ClientTransactionItem {
    @UnsupportedAppUsage
    private List<ResultInfo> mResultInfoList;
    /* TODO(b/78294732)
    @Override
    public int getPostExecutionState() {
        return ON_RESUME;
    }*/
}

Excuse me? TODO state!! 实际上,这个TODO 一直拖到android 13 才被加上,en~~~~。

  • 设计归设计,到android13 为止,framework里从来没有过一个事务集里绑定多个Callback事务的用法,所以 这段逻辑设计的并没有什么用。

第四点,如果Callback事务的结束状态为ON_RESUME,则判断当前Activity状态是更靠近ON_START状态还是ON_PAUSE状态,并将activity状态转换到就近状态(ON_START or ON_PAUSE)。

这里判断当前Activity状态更靠近ON_START还是ON_PAUSE,采用的是路径长度比较法。framework中为Activity定义了九种状态,具体如下:

    public static final int UNDEFINED = -1;
    public static final int PRE_ON_CREATE = 0;
    public static final int ON_CREATE = 1;
    public static final int ON_START = 2;
    public static final int ON_RESUME = 3;
    public static final int ON_PAUSE = 4;
    public static final int ON_STOP = 5;
    public static final int ON_DESTROY = 6;

状态之间的转换路径如下表所示:

上表中置灰的单元格,表示不存在或禁止的状态转换,而单元格中A ~ B 这种写法 表示 从 A到 B状态之间的中间所有状态,如: start 状态为 PRE_CREATE , finish 状态为 DESTROY ,在上表中状态转换路径为 create ~ destroy,表示 activity从 PRE_CREATE 状态转换到 DESTROY 状态,需要经历 create、start 、 resume 、pause 、stop 、 detroy ,即create到destroy之间所有的生命周期变换的过程。同时,我们也称 create~destroy 是 PRE_CREATE到DESTROY状态路径,它的路径长度为6。

如何判断当前生命周期是更靠近ON_START还是ON_PAUSE?我们举个例子来看一下,假如当前的生命周期为ON_STOP,由上述状态路径表可知,从ON_STOP状态转换到ON_START状态的路径为restart、start,长度为2;而由ON_STOP状态转换到ON_PAUSE状态的路径为restart、start~pause,长度为4。因此,当前activity的状态更靠近ON_START。

在路径长度算法的代码里,google给凡是路径中含有destroy状态的长度,赋予了一段惩罚长度,让它的长度增加了10,具体代码如下:

  public int getClosestOfStates(ActivityClientRecord r, int[] finalStates) {
        if (finalStates == null || finalStates.length == 0) {
            return UNDEFINED;
        }
        final int currentState = r.getLifecycleState();
        int closestState = UNDEFINED;
        for (int i = 0, shortestPath = Integer.MAX_VALUE, pathLength; i < finalStates.length; i++) {
            getLifecyclePath(currentState, finalStates[i], false /* excludeLastState */);
            pathLength = mLifecycleSequence.size();
            if (pathInvolvesDestruction(mLifecycleSequence)) {
		//路径中含有destroy状态,增加惩罚长度
                pathLength += DESTRUCTION_PENALTY;
            }
            if (shortestPath > pathLength) {
                shortestPath = pathLength;
                closestState = finalStates[i];
            }
        }
        return closestState;
    }

然而我们可以看一下表格中finish state为 START 和 PAUSE的两列,所有的路径中都不包含 destroy 状态,所以这个惩罚长度的意义何在?

第五步开始,正式执行 事务的execute和postExecute逻辑。这里要谈一下,为什么执行结束状态为 ON_RESUME的事务时,先要在第四步将 状态切换到 ON_START 或 ON_RESUME后,然后才开始去执行事务的逻辑呢?

在Android 10中,结束状态为 ON_RESUME 的事务只有 NewIntentItem,其 excute 方法代码片段如下:

NewIntentItem.java
    public void execute(ClientTransactionHandler client, ActivityClientRecord r,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent");
        client.handleNewIntent(r, mIntents);
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    }

它最终会调用到 activity的performNewIntent方法。

可以看到在这个过程中并没有涉及到生命周期状态的转换。因此,google这段逻辑的意图是:在执行最终状态为ON_RESUME的事务时,先将activity生命周期状态转换到ON_RESUME的临近状态,即ON_START或ON_PAUSE状态,然后再去执行事务,最后在事务执行完毕后,将activity的状态真正地切换到ON_RESUME。

第六步,跳过最后一个状态转换,改为通过显式状态变换去执行。

这里做了一个判断,如果事务组最后一次最终状态与事务集的生命周期状态相同,跳过此事务的最终状态的转换,改由 LifeCycle事务去执行状态转换。

然而,我们来看这样一组事务,ConfigurationChangeItem、NewIntentItem、ConfigurationChangeItem、NewIntentItem,虽然实际编码中并不会写出这样一组事务,但仍可以用来吐槽一下google的这段代码逻辑:

由第二步可知,上述的的事务组最后一次activity状态转换的Callback索引为 1。

final boolean shouldExcludeLastTransition =
                        i == lastCallbackRequestingState && finalState == postExecutionState;
cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);

可以看到,在第二个事务,activity并不会切换到ON_RESUME状态。

然而这段代码最大的问题是,这个判断并不能达成显式状态变换的目标,因为在第四个事务时 activity会被切换到ON_REUSME的目标状态。

有读者可能会提出异议了,作者你举的这个例子是属于特例,代码中不可能这么写。 然而,如果不需要考虑这种特殊情况的话,第二步的索引值计算又有什么作用呢?

executeLifecycleState

这个方法是对事务集中的LifeCycle事务的处理,其代码具体如下:

  private void executeLifecycleState(ClientTransaction transaction) {
      ...
        // Cycle to the state right before the final requested state.
        cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);
        // Execute the final transition with proper parameters.
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
    }

可以看到,cycleToPath是将activity切换到目标生命周期状态的关键方法:

  private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
            ClientTransaction transaction) {
        final int start = r.getLifecycleState();
        final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
        performLifecycleSequence(r, path, transaction);
    }

getLifecyclePath是获取状态路径的方法,关于状态路径在上文中已经有所介绍。

  private void performLifecycleSequence(ActivityClientRecord r, IntArray path,
            ClientTransaction transaction) {
        final int size = path.size();
        for (int i = 0, state; i < size; i++) {
            state = path.get(i);
            switch (state) {
                case ON_CREATE:
                    mTransactionHandler.handleLaunchActivity(r, mPendingActions,
                            null /* customIntent */);
                    break;
                case ON_START:
                    mTransactionHandler.handleStartActivity(r, mPendingActions,
                            null /* activityOptions */);
                    break;
                case ON_RESUME:
                    mTransactionHandler.handleResumeActivity(r, false /* finalStateRequest */,
                            r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
                    break;
                case ON_PAUSE:
                    mTransactionHandler.handlePauseActivity(r, false /* finished */,
                            false /* userLeaving */, 0 /* configChanges */, mPendingActions,
                            "LIFECYCLER_PAUSE_ACTIVITY");
                    break;
                case ON_STOP:
                    mTransactionHandler.handleStopActivity(r, 0 /* configChanges */,
                            mPendingActions, false /* finalStateRequest */,
                            "LIFECYCLER_STOP_ACTIVITY");
                    break;
                case ON_DESTROY:
                    mTransactionHandler.handleDestroyActivity(r, false /* finishing */,
                            0 /* configChanges */, false /* getNonConfigInstance */,
                            "performLifecycleSequence. cycling to:" + path.get(size - 1));
                    break;
                case ON_RESTART:
                    mTransactionHandler.performRestartActivity(r, false /* start */);
                    break;
                default:
                    throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
            }
        }
    }
}

获取到状态路径后,开始遍历路径,按顺序依次切换路径中的activity生命周期状态,直到到达目标状态为止。

在达到目标路径后,会调用Lifecycle事务的excute方法。这里会再一次调用切换到目标状态的逻辑,不过实际状态切换时,源码里做了状态判重的操作,并不会造成任何不良的影响。

以上就是Android10 客户端事务管理ClientLifecycleManager源码解析的详细内容,更多关于Android10 客户端事务管理的资料请关注我们其它相关文章!

(0)

相关推荐

  • Android 10 启动Init进程解析

    目录 按下电源键时,android做了啥? init进程解析 FirstStageMain SetupSelinux SecondStageMain init.rc 解析 按下电源键时,android做了啥? 当我们按下电源键时,手机开始上电,并从地址0x00000000处开始执行,而这个地址通常是Bootloader程序的首地址. bootloader是一段裸机程序,是直接与硬件打交道的,其最终目的是“初始化并检测硬件设备,准备好软件环境,最后调用操作系统内核”.除此之外,bootloader

  • Android 10 启动之servicemanager源码解析

    目录 正文 获取服务 注册服务 正文 上一篇文章: Android 10 启动分析之Init篇 (一) 在前文提到,init进程会在在Trigger 为init的Action中,启动servicemanager服务,这篇文章我们就来具体分析一下servicemanager服务,它到底做了哪些事情. servicemanager服务的源码位于/frameworks/native/cmds/servicemanager/service_manager.c,我们将从这个类的入口开始看起. int ma

  • Android10 App启动Activity源码分析

    目录 正文 ActivityThread的main方法 Application Context对象 LaunchActivityItem ClientLifecycleManager ClientTransaction TransactionExecutor executeLifecycleState方法 正文 上一篇: Android 10 App启动分析之进程创建篇(一) 上一篇文章,我们探讨了App启动过程中进程创建及初始化的流程,这篇文章我们接着上篇的内容,继续探讨App的Applica

  • Android10 启动之SystemServer源码分析

    目录 正文 createSystemContext startBootstrapServices startCoreServices startOtherServices 正文 上一篇文章: # Android 10 启动分析之Zygote篇 (三) 紧接着上一篇文章的内容,我们从这篇文章开始来分析一下 SystemServer. system_server 进程承载着整个framework的核心服务,例如创建 ActivityManagerService.PowerManagerService

  • Android10 启动Zygote源码解析

    目录 app_main ZygoteInit preload preloadClasses preloadResources preloadSharedLibraries forkSystemServer app_main 上一篇文章: # Android 10 启动分析之servicemanager篇 (二) 在init篇中有提到,init进程会在在Trigger 为late-init的Action中,启动Zygote服务,这篇文章我们就来具体分析一下Zygote服务,去挖掘一下Zygote负

  • Android10 App 启动分析进程创建源码解析

    目录 正文 RootActivityContainer ActivityStartController 调用startActivityUnchecked方法 ActivityStackSupervisor 启动进程 RuntimeInit.applicationInit这个方法 正文 从前文# Android 10 启动分析之SystemServer篇 (四)中可以得知,系统在完成所有的初始化工作后,会通过 mAtmInternal.startHomeOnAllDisplays(currentU

  • Android10 客户端事务管理ClientLifecycleManager源码解析

    目录 正文 ClientLifecycleManager ClientTransaction TransactionExecutor executeLifecycleState 正文 在Android 10 App启动分析之Activity启动篇(二)一文中,简单地介绍了Activity的生命周期管理器是如何调度Activity进入onCreate生命周期的流程.这篇文章,我们将详细地分析framework中activity的生命周期管理功能,从更宏观的角度来更全面地了解生命周期及相关事务的工作

  • Django ORM 查询管理器源码解析

    ORM 查询管理器 对于 ORM 定义: 对象关系映射, Object Relational Mapping, ORM, 是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换.从效果上说,它其实是创建了一个可在编程语言里使用的"虚拟对象数据库".ORM 能大大简化并抽象数据库的操作. 假设 django 的一个工程中包含一个名为 Book 的模块(model), 在 views.py 的函数中可能会写出查询语句: # views.py def index(requ

  • Mybatis源码解析之事务管理

    目录 Mybatis事务管理 和Spring整合后的事务管理 Mybatis事务管理 我们可以在mybatis-config.xml中配置事务管理器的实现 <transactionManager type="JDBC"/> 当值为JDBC时,事务管理实现类为JdbcTransaction,底层利用数据库的Connection来管理事务 当值为MANAGED时,事务管理实现类为ManagedTransactionFactory,但它对事务的管理是一个空实现,将事务管理交给外部

  • Spring源码解析之编程式事务

    一.前言 在Spring中,事务有两种实现方式: 编程式事务管理: 编程式事务管理使用TransactionTemplate可实现更细粒度的事务控制.声明式事务管理: 基于Spring AOP实现.其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务. 声明式事务管理不需要入侵代码,通过@Transactional就可以进行事务操作,更快捷而且简单(尤其是配合spring boot自动配置,可以说是精简至极!),且大部分业务都可

  • 从Spring源码解析事务失效的原因

    目录 一.前言 二.方法不是 public 的 三.内部方法间调用导致事务失效 四.异常类型是否配置正确 五.异常被catch住 一.前言 1.Bean是否是代理对象 2.入口函数是否是public的 3.数据库是否支持事务(Mysql的Mvlsam不支持事务),行锁才支持事务 4.切点是否配置正确 5.内部方法间调用导致事务失效 因为this不是代理对象,可以配置 expose-proxy="true",就可以通过AopContext.currentProxy()获取到当前类的代理对

  • Java Spring AOP源码解析之事务实现原理

    目录 不用Spring管理事务? 编程式事务管理 使用PlatformTransactionManager 使用TransactionTemplate 声明式事务管理 使用@Transactional注解 源码解析 参考博客 总结 不用Spring管理事务? 让我们先来看一下不用spring管理事务时,各种框架是如何管理事务的 使用JDBC来管理事务 使用Hibernate来管理事务 业务逻辑和事务代码是耦合到一块的,并且和框架的具体api绑定了.当我们换一种框架来实现时,里面对事务控制的代码就

  • Mango Cache缓存管理库TinyLFU源码解析

    目录 介绍 整体架构 初始化流程 读流程 写流程 事件处理机制 主流程 write 清理工作 缓存管理 什么是LRU? 什么是SLRU? 什么是TinyLFU? mango Cache中的TinyLFU counter counter的初始化 counter的使用 lruCache slruCache filter TinyLFU的初始化 TinyLFU写入 TinyLFU访问 增加entry的访问次数 估计entry访问次数 总结 介绍 据官方所述,mango Cache是对Guava Cac

  • Spring源码解析之事务传播特性

    一.使用方式 可以采用Transactional,配置propagation即可. 打开org.springframework.transaction.annotation.Transactional可见默认传播特性是REQUIRED. /** * The transaction propagation type. * <p>Defaults to {@link Propagation#REQUIRED}. * @see org.springframework.transaction.inte

随机推荐