傳統上,許多 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
某些語言可以使用 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()
來傳回 RowResult
或 DocResult
,並使用 executeAsync()
來傳回 CompletableFuture<T>
,其中型別參數是其中一個結果類型。