001/** 002 * Copyright (c) 2015-2022, Michael Yang 杨福海 (fuhai999@gmail.com). 003 * <p> 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * <p> 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * <p> 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package io.jboot.db.transactional; 017 018import com.jfinal.aop.Invocation; 019import io.jboot.utils.ClassUtil; 020import io.jboot.utils.NamedThreadFactory; 021import io.jboot.utils.StrUtil; 022 023import java.util.Map; 024import java.util.concurrent.*; 025 026public class TransactionalManager { 027 028 private static TransactionalManager instance = new TransactionalManager(); 029 030 public static TransactionalManager me() { 031 return instance; 032 } 033 034 035 private Map<String, ExecutorService> executorServiceMap = new ConcurrentHashMap<>(); 036 private ThreadFactory threadFactory = new NamedThreadFactory("Transactional", true); 037 038 //当未配置线程池名称的时候,是否使用 threadFactory 来执行 039 private boolean runDefaultWithoutConfigName = false; 040 041 042 public void addExecutorService(String name, ExecutorService service) { 043 executorServiceMap.put(name, service); 044 } 045 046 public ExecutorService getExecutorService(String name) { 047 return executorServiceMap.get(name); 048 } 049 050 public void removeExecutorService(String name) { 051 executorServiceMap.remove(name); 052 } 053 054 public Map<String, ExecutorService> getExecutorServiceMap() { 055 return executorServiceMap; 056 } 057 058 public ThreadFactory getThreadFactory() { 059 return threadFactory; 060 } 061 062 public void setThreadFactory(ThreadFactory threadFactory) { 063 this.threadFactory = threadFactory; 064 } 065 066 public boolean isRunDefaultWithoutConfigName() { 067 return runDefaultWithoutConfigName; 068 } 069 070 public void setRunDefaultWithoutConfigName(boolean runDefaultWithoutConfigName) { 071 this.runDefaultWithoutConfigName = runDefaultWithoutConfigName; 072 } 073 074 public Future<Boolean> execute(String byName, Callable<Boolean> callable, Invocation inv) { 075 if (StrUtil.isBlank(byName)) { 076 FutureTask<Boolean> task = new FutureTask<>(callable); 077 threadFactory.newThread(task).start(); 078 return task; 079 } 080 081 082 ExecutorService executorService = executorServiceMap.get(byName); 083 if (executorService != null) { 084 return executorService.submit(callable); 085 } 086 087 if (!runDefaultWithoutConfigName) { 088 throw new IllegalStateException("Can not find threadPoolName: \"" + byName + "\" for @Transactional() in method: " 089 + ClassUtil.buildMethodString(inv.getMethod()) 090 + ".\n Please invoke TransactionalManager.me().addExecutorService() to configure transactional threadPool on application started."); 091 } 092 093 094 FutureTask<Boolean> task = new FutureTask<>(callable); 095 threadFactory.newThread(task).start(); 096 return task; 097 } 098 099 100}