2016-11-16 6 views
0

私はspring mvc webを持っており、いくつかのテーブルのアップデートを実行したいと思います。リンクをクリックすると、別のタスクを実行するためにタスクが完了するまで待つ必要があります。各リンクは別のテーブルに対応していますが、処理を高速化したい場合は、どのように改善しますか? enter image description here複数のテーブルを更新するspring mvcコントローラを作成するには?

コントローラクラス

public class AdminController{ 
    @Autowired 
    public SessionFactory sessionFactory; 

    @Autowired 
    private ThreadPoolTaskExecutor taskExecutor; 

    @Autowired 
    public HashMap<Long, ICollector> collectors; 

    @RequestMapping(value = "/config/configcollectlist",method = RequestMethod.GET) 
    public String getConfigCollectist(ModelMap model) 
    { 
     Session session = sessionFactory.openSession(); 
     List<DbConfigCollect> configCollects = (List<DbConfigCollect>)session.createCriteria(DbConfigCollect.class).list(); 
     session.close(); 

     model.addAttribute("configCollects", configCollects); 
     return "admin/config/configcollectlist";  
    } 

    @RequestMapping(value = "/config/configcollectorlist",method = RequestMethod.GET) 
    public String getConfigCollectorist(ModelMap model) 
    { 
     Session session = sessionFactory.openSession(); 
     List<DbConfigCollector> configCollectors = (List<DbConfigCollector>)session.createCriteria(DbConfigCollector.class).list(); 
     session.close(); 

     model.addAttribute("configCollectors", configCollectors); 
     return "admin/config/configcollectorlist";  
    } 
} 

タスククラス更新

public class CollectorPropertyRED_UK_PPD implements ICollector{ 
    @Autowired 
    private ThreadPoolTaskExecutor taskExecutor; 

    @Autowired 
    public SessionFactory sessionFactory; 

    @Override 
    public void collect(DbConfigCollect inDbConfigCollect) 
    { 
     taskExecutor.execute(new CollectorPropertyRED_UK_PPDTask(sessionFactory, inDbConfigCollect)); 
    } 
} 

public class CollectorPropertyRED_UK_PPDTask extends CollectorTaskBase { 
    public enum COLLECT_PARAMETER_PAPER_COREACUK_FILE { 
     FILE_INPUT, 
    }; 

    public final static String FILE_SUFFIX_CSV = ".csv"; 

    public CollectorPropertyRED_UK_PPDTask(SessionFactory sessionFactory, 
      DbConfigCollect inDbConfigCollect) { 
     super(sessionFactory, inDbConfigCollect); 
    } 

    public void run() { 
     String[] parameters = this.myDbConfigCollect.getParameters().split(";"); 

     // load file 
     File[] sourceFiles = new File(
       parameters[COLLECT_PARAMETER_PAPER_COREACUK_FILE.FILE_INPUT 
         .ordinal()]).listFiles(); 

     int totalCount = 0; 
     for (int i = 0; i < sourceFiles.length; i++) { 

      if (sourceFiles[i].getName().endsWith(FILE_SUFFIX_CSV)) { 
       String timeStamp = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(Calendar.getInstance().getTime()); 
       String fileName = sourceFiles[i].getName(); 

       CSVReader reader = null; 
       int count = 0; 
       try { 
        reader = new CSVReader(new FileReader(sourceFiles[i])); 
        String[] currLine = null; 
        SimpleDateFormat dateFormat = new SimpleDateFormat(
          "yyyy-MM-dd HH:mm"); 

        while ((currLine = reader.readNext()) != null) { 
         String unique_id = currLine[0]; 
         ++count; 
         updateToDb(sessionFactory,currLine); 

        } 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } finally { 
        if (reader != null) { 
         try { 
          reader.close(); 
         } catch (Exception e) { 
         } 
        } 
       } 
      } 
     } 
    } 
} 

: 私はasync request guideに従うことを試してみましたが、期待どおりに動作しません。同じURLを使用してブラウザをリフレッシュすると、すぐにコントローラの応答が返されますが、doSlowWork()メソッドは前のタスクが完了するまで待つ必要があります。ここに私のコードです。

コントローラクラス

@Autowired 
HelloService helloService; 
Logger logger = LoggerFactory.getLogger(AdminController.class); 
@RequestMapping(value ="/helloAsync", method = RequestMethod.GET) 
    public Callable<String> sayHelloAsync() { 
    System.out.println("Entering controller"); 

    Callable<String> asyncTask = new Callable<String>() { 

     @Override 
     public String call() throws Exception { 
     return helloService.doSlowWork(); 
     } 
    }; 

    return asyncTask; 
    } 

asynctaskクラス

@Service 
public class HelloService { 
    Logger logger = LoggerFactory.getLogger(HelloService.class); 

    public String doSlowWork() { 

     Random rand = new Random(); 

     int n = rand.nextInt(50) + 1; 

     System.out.println("start: "+n); 

    try { 
     Thread.sleep(10000); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 

    System.out.println("end: "+ n); 
    return "index";  // return view's name 
    } 
} 

出力

INFO 2016-11-16 15:49:37,706 [http-bio-8080-exec-16] com.exbidata.db.mvc.controller.admin.AdminController - Entering controller 
INFO 2016-11-16 15:49:37,710 [http-bio-8080-exec-16] com.exbidata.db.mvc.controller.admin.AdminController - Leaving controller 
INFO 2016-11-16 15:49:37,720 [taskExecutor-1] com.exbidata.db.mvc.controller.admin.HelloService - Start slow work 
INFO 2016-11-16 15:49:38,201 [http-bio-8080-exec-13] com.exbidata.db.mvc.controller.admin.AdminController - Entering controller 
INFO 2016-11-16 15:49:38,202 [http-bio-8080-exec-13] com.exbidata.db.mvc.controller.admin.AdminController - Leaving controller 
INFO 2016-11-16 15:49:38,975 [http-bio-8080-exec-15] com.exbidata.db.mvc.controller.admin.AdminController - Entering controller 
INFO 2016-11-16 15:49:38,976 [http-bio-8080-exec-15] com.exbidata.db.mvc.controller.admin.AdminController - Leaving controller 
INFO 2016-11-16 15:49:47,721 [taskExecutor-1] com.exbidata.db.mvc.controller.admin.HelloService - finish slow work 
INFO 2016-11-16 15:49:47,723 [taskExecutor-1] com.exbidata.db.mvc.controller.admin.HelloService - Start slow work 
INFO 2016-11-16 15:49:57,724 [taskExecutor-1] com.exbidata.db.mvc.controller.admin.HelloService - finish slow work 
INFO 2016-11-16 15:49:57,726 [taskExecutor-1] com.exbidata.db.mvc.controller.admin.HelloService - Start slow work 
INFO 2016-11-16 15:50:07,726 [taskExecutor-1] com.exbidata.db.mvc.controller.admin.HelloService - finish slow work 

答えて

1

あなたは、代わりに

のWi春非同期リクエスト処理機能を使用する必要がありますServlet 3.0では、非同期サポートが追加されました。まず、あなたは次のように代わりに呼び出し可能な文字列の戻り値を返すの既存のコントローラハンドラメソッドから、

<servlet> 
    <servlet-name>dispatcher</servlet-name> 
    <servlet- class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <load-on-startup>1</load-on-startup> 
    <!-- turn on async support for servlet --> 
    <async-supported>true</async-supported> 
</servlet> 

をあなたのweb.xmlの非同期サポートを有効にする必要があり

@RequestMapping(value = "/config/configcollectlist",method = RequestMethod.GET) 
    public Callable<String> getConfigCollectist(ModelMap model) 
    { 
    Callable<String> asyncTask = new Callable<String>() { 

     @Override 
     public String call() throws Exception { 

     Session session = sessionFactory.openSession(); 
     List<DbConfigCollect> configCollects = (List<DbConfigCollect>)session.createCriteria(DbConfigCollect.class).list(); 
     session.close(); 
     model.addAttribute("configCollects", configCollects); 

     return "admin/config/configcollectlist"; 
    } 
    }; 

    return asyncTask; 
} 

また、あなたは、春のアプリケーションコンテキストを設定する必要があります非同期サポート用。

<mvc:annotation-driven> 
    <mvc:async-support default-timeout="30000" task-executor="taskExecutor"/> 
</mvc:annotation-driven> 
<!-- modify the parameters of thread pool --> 
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> 
    <property name="corePoolSize" value="5"/> 
    <property name="maxPoolSize" value="50"/> 
    <property name="queueCapacity" value="10"/> 
    <property name="keepAliveSeconds" value="120"/> 
</bean> 
+0

(私は、XMLベースの構成を記載している)私はちょうど私のコードを更新し、あなたが見 – peter

+0

を持ってくださいだろう、あなたは完了するために、以前のを待っている現在のスレッドを示し、あなたのログ/エラーを提供していただけますか? – ScanQR

+0

さて、この出力は私がリフレッシュボタンを数回押して生成したものです。 – peter

関連する問題