文件首頁
X DevAPI 使用者指南
下載本手冊
PDF (美式信紙) - 1.4Mb
PDF (A4) - 1.4Mb


X DevAPI 使用者指南  /  CRUD 操作  /  同步與非同步執行

3.3 同步與非同步執行

傳統上,許多 MySQL 驅動程式在執行 SQL 語句時使用同步方法。這表示連線開啟和執行查詢等操作會被封鎖直到完成,這可能需要很長的時間。為了允許平行執行,開發人員必須編寫多執行緒應用程式。

任何支援 X Protocol 的 MySQL 用戶端都可以提供非同步執行,可以使用回呼、Promise,或在實際需要時明確等待特定結果。

非同步操作

使用回呼是實作非同步操作的常見方法。當指定回呼函數時,CRUD 操作是非封鎖的,這表示即使尚未擷取資料庫的結果,也會立即呼叫下一個語句。只有在結果可用時才會呼叫回呼。

Node.js JavaScript 程式碼

var employees = db.getTable('employee');

employees.select('name', 'age')
  .where('name like :name')
  .orderBy('name')
  .bind('name', 'm%')
  .execute(function (row) {
    // do something with a row
  })
  .catch(err) {
    // Handle error
  });

C# 程式碼

var employees = db.GetTable("employee");

var select = employees.Select("name", "age")
  .Where("name like :name")
  .OrderBy("name")
  .Bind("name", "m%")
  .ExecuteAsync();

select.ContinueWith(t =>
{
  if (t.Exception != null)
  {
    // Handle error
  }
  // Do something with the resultset
});

Java 程式碼

Table employees = db.getTable("employee");

// execute the query asynchronously, obtain a future
CompletableFuture<RowResult> rowsFuture = employees.select("name", "age")
  .where("name like :name")
  .orderBy("name")
  .bind("name", "m%").executeAsync();

// dependent functions can be attached to the CompletableFuture

MySQL Shell JavaScript 程式碼

// Asynchronous execution is not implemented

MySQL Shell Python 程式碼

// Asynchronous execution is not implemented

Python 程式碼

// Asynchronous execution is not implemented

C++ 程式碼

// Asynchronous execution is not implemented

使用 Await 的非同步操作

某些語言可以使用 async/await 模式。

C# 程式碼

Task<RowResult> getEmployeesTask = employees.Select("name", "age")
  .Where("name like :name").OrderBy("name")
  .Bind("name", "m%").ExecuteAsync();

// Do something else while the getEmployeesTask is executing in the background

// at this point we are ready to get our results back. If it is not done,
// this will block until done
RowResult res = await getEmployeesTask;

foreach (var row in res.FetchAll())
{
  // use row object
}

Connector/Node.js 對所有網路操作都使用 Promise 的非同步操作。請參閱其他範例。

Java 程式碼

Table employees = db.getTable("employee");

// execute the query asynchronously, obtain a future
CompletableFuture<RowResult> rowsFuture = employees.select("name", "age")
  .where("name like :name")
  .orderBy("name")
  .bind("name", "m%").executeAsync();

// wait until it's ready
RowResult rows = rowsFuture.get();

語法差異

根據您使用的語言,X DevAPI 可能會實作一個函數,例如 executeAsync() 以取代 execute([mysqlx.Async]) 或作為 execute([mysqlx.Async]) 的補充。

例如,在 Node.js 環境中,所有執行都是非同步的。因此,Connector/Node.js 不需要區分 execute()executeAsync()。為了表示非同步的預設執行,Connector/Node.js 僅實作 execute(),它會傳回 JavaScript Promise 物件。

強型別程式設計語言(例如 Java 或 C#)可以利用針對同步和非同步執行使用兩個不同名稱的 API 呼叫。這兩個呼叫可以具有不同的傳回類型。例如,Connector/J 可以使用 execute() 來傳回 RowResultDocResult,並使用 executeAsync() 來傳回 CompletableFuture<T>,其中型別參數是其中一個結果類型。