Docs 菜单
Docs 主页
/ / /
C 驱动程序
/

事务

在此页面上

  • Overview
  • 事务 API
  • Convenient API
  • Core API
  • 事务示例
  • 更多信息
  • API 文档

在本指南中,您可以学习;了解如何使用C驾驶员来执行事务。事务允许您执行一系列仅在提交整个ACID 事务后才更改数据的操作。如果ACID 事务中的任何操作不成功,则库会停止ACID 事务并在所有数据更改变得可见之前将其丢弃。此功能称为原子性。

在MongoDB中,事务在逻辑会话中运行。 会话是您打算按顺序运行的一组相关读取或写入操作。 会话可为一群组操作启用因果一致性,并允许您在符合ACID的ACID 事务中运行操作,该ACID 事务满足原子性、一致性、隔离性性和持久性的预期。 MongoDBACID 一致性保证ACID 事务操作中涉及的数据保持一致,即使操作遇到意外错误。

使用C驾驶员时,您可以从 mongoc_client_t实例创建新会话。然后,您可以使用生成的 mongoc_client_session_t实例来执行事务。

警告

仅应将 mongoc_client_session_t 与创建它的 mongoc_client_t(或关联的 mongoc_database_tmongoc_collection_t)一起使用。将 mongoc_client_session_t 与其他 mongoc_client_t 一起使用会导致操作错误。

在本节中,您可以学习;了解C驾驶员提供的ACID 事务API。在开始ACID 事务之前,必须在 mongoc_client_t实例上使用 mongoc_client_start_session() 函数来创建 mongoc_client_session_t。然后,您可以使用以下任一 API 来执行ACID 事务:

  • Convenient API

  • Core API

C驾驶员提供了一个便捷事务 API来管理ACID 事务生命周期。通过使用mongoc_client_session_with_transaction() 函数在ACID 事务中运行自定义回调来实施此API 。mongoc_client_session_with_transaction() 函数执行以下任务:

  • 启动ACID 事务

  • 通过结束ACID 事务或重试来处理错误,例如当操作导致 TransientTransactionError

  • 提交ACID 事务

本指南的事务示例部分演示了如何使用此API来执行ACID 事务。

或者,您可以在 mongoc_client_session_t实例中使用以下函数,更好地控制ACID 事务生命周期:

function
说明

mongoc_client_session_start_transaction()

Starts a new transaction, configured with the given options, on this session. Returns false and sets the provided error if there are invalid arguments, such as a session with a transaction already in progress. To learn more about this function, see the startTransaction() page in the Server manual.

mongoc_client_session_abort_transaction()

Ends the active transaction for this session. Returns false and sets the provided error if there is no active transaction for the session or the transaction has been committed or ended. To learn more about this function, see the abortTransaction() page in the Server manual.

mongoc_client_session_commit_transaction()

Commits the active transaction for this session. Returns an error if there is no active transaction for the session or if the transaction was ended. To learn more about this function, see the commitTransaction() page in the Server manual.

mongoc_client_session_destroy()

Aborts any transactions in progress and ends this session. Frees all client resources associated with this session.

mongoc_client_session_t要学习;了解有关检索 属性和修改可变会话属性的函数的更多信息,请参阅API文档。

此示例定义了一个回调函数,用于修改sample_bank数据库集合中银行ACID 事务的数据。 该代码执行以下操作:

  1. 定义回调函数,该函数接收mongoc_client_session_t实例作为参数。

  2. 创建mongoc_collection_t实例以访问权限目标集合。

  3. 指定帐号和账户之间转账的金额。

  4. 更新客户余额以反映转账情况。

  5. 记录带有时间戳的ACID 事务收据。

  6. 如果ACID 事务提交成功,则打印一条消息。

bool
transaction_callback (mongoc_client_session_t *session, void *ctx, bson_t **reply,
bson_error_t *error)
{
BSON_UNUSED(ctx);
BSON_UNUSED(reply);
mongoc_client_t *client = mongoc_client_session_get_client (session);
mongoc_collection_t *checking = mongoc_client_get_collection (client, "sample_bank", "checking");
mongoc_collection_t *savings = mongoc_client_get_collection (client, "sample_bank", "savings");
mongoc_collection_t *receipts = mongoc_client_get_collection (client, "sample_bank", "receipts");
const char *account_id = "123456";
int transfer_amount = 1000;
bson_t *filter = BCON_NEW ("account_id", BCON_UTF8 (account_id));
bson_t *update_decrement = BCON_NEW ("$inc", "{", "balance", BCON_INT32 (-transfer_amount), "}");
bson_t *update_increment = BCON_NEW ("$inc", "{", "balance", BCON_INT32 (transfer_amount), "}");
if (!mongoc_collection_update_one (checking, filter, update_decrement, NULL, NULL, &error)) {
fprintf (stderr, "Failed to update checking account: %s\n", error.message);
return false;
}
if (!mongoc_collection_update_one (savings, filter, update_increment, NULL, NULL, &error)) {
fprintf (stderr, "Failed to update savings account: %s\n", error.message);
return false;
}
bson_t *receipt = BCON_NEW ("account_id", BCON_UTF8 (account_id),
"amount", BCON_INT32 (transfer_amount),
"timestamp", BCON_DATE_TIME (bson_get_monotonic_time ()));
if (!mongoc_collection_insert_one (receipts, receipt, NULL, NULL, &error)) {
fprintf (stderr, "Failed to insert receipt: %s\n", error.message);
return false;
}
mongoc_collection_destroy (checking);
mongoc_collection_destroy (savings);
mongoc_collection_destroy (receipts);
bson_destroy (filter);
bson_destroy (update_decrement);
bson_destroy (update_increment);
bson_destroy (receipt);
printf ("Transaction successful!");
return true;
}

然后,运行以下代码以执行ACID 事务。 此代码完成以下操作:

  1. 使用 mongoc_client_start_session() 函数从客户端创建会话。

  2. 调用mongoc_client_session_with_transaction()函数来管理ACID 事务,并将会话和回调作为参数传递。

mongoc_client_session_t *session = mongoc_client_start_session (client, NULL, NULL);
if (!session) {
fprintf (stderr, "Failed to start session\n");
mongoc_client_destroy (client);
return EXIT_FAILURE;
}
bool result =
mongoc_client_session_with_transaction (session,
(mongoc_client_session_with_transaction_cb_t) transaction_callback,
NULL, NULL, NULL, &error);
if (!result) {
fprintf (stderr, "Transaction error: %s\n", error.message);
}
mongoc_client_session_destroy (session);
mongoc_client_destroy (client);
mongoc_cleanup ();
Transaction successful!

注意

不支持并行操作

C驾驶员不支持在单个ACID 事务中运行并行操作。

如果您使用的是MongoDB Server v8.0 或更高版本,则可以使用批量写入操作在单个ACID 事务中对多个命名空间执行写入操作。有关更多信息,请参阅 批量写入操作指南。

要学习;了解有关本指南中提到的概念的更多信息,请参阅MongoDB Server手册中的以下页面:

要学习;了解有关ACID compliance的更多信息,请参阅什么是数据库管理系统中的ACID属性? MongoDB网站上的文章。

要学习;了解有关本指南中讨论的任何类型或函数的更多信息,请参阅以下API文档:

后退

批量写入操作