文档首页
X DevAPI 用户指南
下载本手册

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

3.3 同步与异步执行

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

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

异步操作

使用回调是实现异步操作的非常常见的方法。当指定回调函数时,CRUD 操作是非阻塞的,这意味着即使数据库的结果尚未获取,也会立即调用下一个语句。只有在结果可用时才会调用回调。

Node.js JavaScript 代码

Press CTRL+C to copy
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# 代码

Press CTRL+C to copy
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 代码

Press CTRL+C to copy
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 代码

Press CTRL+C to copy
// Asynchronous execution is not implemented

MySQL Shell Python 代码

Press CTRL+C to copy
// Asynchronous execution is not implemented

Python 代码

Press CTRL+C to copy
// Asynchronous execution is not implemented

C++ 代码

Press CTRL+C to copy
// Asynchronous execution is not implemented

使用 Awaits 的异步操作

一些语言可以使用 async/await 模式。

C# 代码

Press CTRL+C to copy
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 代码

Press CTRL+C to copy
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>,其中类型参数是结果类型之一。