protected void checkRunningTxnExceedLimit(TransactionState.LoadJobSourceType sourceType) throws RunningTxnExceedException {
        switch (sourceType) {
            case ROUTINE_LOAD_TASK:
                // no need to check limit for routine load task:
                // 1. the number of running routine load tasks is limited by Config.max_routine_load_task_num_per_be
                // 2. if we add routine load txn to runningTxnNums, runningTxnNums will always be occupied by routine load,
                //    and other txn may not be able to submitted.
                break;
            case LAKE_COMPACTION:
                // no need to check limit for cloud native table compaction.
                // high frequency and small batch loads may cause compaction execute rarely.
                break;
            default:
                if (runningTxnNums >= Config.max_running_txn_num_per_db) {
                    throw new RunningTxnExceedException("current running txns on db " + dbId + " is "
                            + runningTxnNums + ", larger than limit " + Config.max_running_txn_num_per_db);
                }
                break;
        }
    }
@Test
    public void testCheckRunningTxnExceedLimit() {
        int maxRunningTxnNumPerDb = Config.max_running_txn_num_per_db;
        DatabaseTransactionMgr mgr = new DatabaseTransactionMgr(0, masterGlobalStateMgr);
        Deencapsulation.setField(mgr, "runningTxnNums", maxRunningTxnNumPerDb);
        ExceptionChecker.expectThrowsNoException(
                () -> mgr.checkRunningTxnExceedLimit(TransactionState.LoadJobSourceType.ROUTINE_LOAD_TASK));
        ExceptionChecker.expectThrowsNoException(
                () -> mgr.checkRunningTxnExceedLimit(TransactionState.LoadJobSourceType.LAKE_COMPACTION));
        ExceptionChecker.expectThrows(RunningTxnExceedException.class,
                () -> mgr.checkRunningTxnExceedLimit(TransactionState.LoadJobSourceType.BACKEND_STREAMING));
    }