X DevAPI 用户指南  / 第三章CRUD操作  /  3.3 同步与异步执行

3.3 同步与异步执行

传统上,许多 MySQL 驱动程序在执行 SQL 语句时使用同步方法。这意味着诸如打开连接和执行查询之类的操作在完成之前会被阻塞,这可能需要很长时间。为了允许并行执行,开发人员必须编写多线程应用程序。

任何支持 X 协议的 MySQL 客户端都可以提供异步执行,可以使用回调、Promises,也可以在实际需要时显式等待特定结果。

异步操作

使用回调是实现异步操作的一种非常常见的方式。当指定回调函数时,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 外壳 JavaScript 代码

// Asynchronous execution is not implemented

MySQL 外壳 Python 代码

// Asynchronous execution is not implemented

Python代码

// Asynchronous execution is not implemented

C++代码

// Asynchronous execution is not implemented

使用等待的异步操作

一些语言可以使用异步/等待模式。

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 对所有网络操作使用 Promises 异步操作。请参阅其他示例。

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()返回 RowResultorDocResultexecuteAsync()返回 a CompletableFuture<T>,其中类型参数是其中一种结果类型。