2011-12-26 49 views
6

剛開始玩。文檔討論了Play如何可以異步運行。如何在Play框架中運行異步/非阻塞MySQL查詢?

但是,如何在異步運行Play時運行MySQL查詢?正常的MySQL查詢是阻塞的,對吧?所以這是行不通的。

Node.js有它自己的非阻塞MySQL客戶端只是爲了這個目的,但我找不到類似的Play。

如何在異步Play應用程序中運行MySQL查詢?

回答

3

查看此鏈接Asynchronous jobs在播放框架中。

+1

謝謝。我不確定我是否理解工作如何不受阻礙。如果我的MySQL客戶端阻塞,那麼在一份工作中使用它仍然會阻塞,不是嗎?或者,每次創建新作業時,Play是否會產生一個新線程?在這種情況下,它有點失敗了異步框架的整個目的。 – Continuation 2011-12-26 05:21:34

+2

@Continuation我認爲你可能會混淆「異步框架」與「框架能夠異步操作」關於玩!框架?正如鏈接文檔所解釋的那樣,您可以使用作業從HTTP請求中異步執行長時間運行的操作,並對其他傳入的HTTP請求執行非阻塞操作。 – tmbrggmn 2011-12-27 10:02:57

2

播放作業在單獨的線程中執行並釋放主要的http線程。然後,當完成後Job(包裝在Promise對象中)返回時,主HTTP線程將從其停止的位置開始。

因此,主要的http線程沒有被阻止,並且可以用於處理其他傳入的http請求。

0

通常,執行SQL調用到DB通常是按順序執行阻止和執行的。 Play對異步執行有很好的支持,可以提高應用程序的性能。

工作代碼樣本播放2.0

public static Result slow() { 
    Logger.debug("slow started"); 

    // Start execution 
    Promise<DataObject> userObject1 = SlowQuery.getUser(440); 
    Promise<DataObject> userObject2 = SlowQuery.getCategory(420); 
    // ... here execution is already in progress ... 

    // Map to Promise Objects 
    Promise<DataObject> res1 = userObject1.map(new Function<DataObject, DataObject>() { 
     public DataObject apply(DataObject res) { 
      Logger.debug("Got result (userObject1): " + res.toString()); 
      return res; 
     } 
    }); 

    Promise<DataObject> res2 = userObject2.map(new Function<DataObject, DataObject>() { 
     public DataObject apply(DataObject res) { 
      Logger.debug("Got result (userObject2): " + res.toString()); 
      return res; 
     } 
    }); 

    // here we wait for completion - this blocks 
    userObject1.getWrappedPromise().await(); 
    userObject2.getWrappedPromise().await(); 

    // the result is available 
    Logger.debug(res1.get().toString()); 
    Logger.debug(res2.get().toString()); 

    Logger.debug("slow finished"); 
    return ok("done"); 
} 

隨時使用社區的wiki功能,可以提高 - 我相信某些部分可以被縮短。

+7

但是隻要數據庫客戶端本身阻塞,Play線程也會被阻塞,不是嗎? Node.js提供了一個非阻塞的MySQL客戶端,以解決這個問題。但我不認爲Play提供任何非阻塞的DB客戶端。你能解釋一下你的代碼是如何將數據庫調用變成非阻塞的? – Continuation 2012-05-01 12:29:19