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

事务

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

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

使用Ruby驾驶员时,可以通过在客户端上调用 start_session 方法来启动会话。然后,您可以在会话中执行事务。

警告

仅在创建会话的 Mongo::Client 上运行的操作中使用会话。使用具有不同 Mongo::Client 的会话会导致操作错误。

MongoDB在某些客户端会话中实现因果一致性。因果一致性模型ACID 一致性保证在分布式系统中,会话中的操作按因果顺序运行。客户端观察到的结果与因果关系或操作之间的依赖关系一致。示例,如果您执行一系列操作,其中一个操作在逻辑上依赖于另一个操作的结果,则任何后续读取都会反映这种依赖关系。

为了保证因果一致性,客户端端会话必须满足以下要求:

  • 启动会话时,驾驶员必须启用因果一致性选项。该选项默认启用。

  • 操作必须在单个线程的单个会话中运行。否则,会话或线程必须相互传达optime和集群时间值。 要查看传达这些值的两个会话的示例,请参阅MongoDB Server手册中的 因果一致性示例

  • 您必须使用 :majority读关注(read concern)。

  • 您必须使用 :majority写关注(write concern)。这是默认的写关注(write concern)值。

下表描述了因果一致会话提供的ACID 一致性保证:

保证
说明

读取写入操作

读取操作会反映之前写入操作的结果。

单调读取

读取操作不会返回反映比先前读取操作更早的数据状态的结果。

单调写入

如果写入操作必须先于其他写入操作,则服务器会先运行此写入操作。

示例,如果调用 insert_one() 插入文档,然后调用 update_one() 修改插入的文档,则服务器首先运行插入操作。

读取后写入

如果写入操作必须在其他读取操作之后执行,服务器会先执行读取操作。

示例,如果您调用 find() 来检索文档,然后调用 delete_one() 来删除检索到的文档,则服务器会先运行查找操作。

提示

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

调用 start_session 方法启动会话后,您可以使用 Mongo::Session 类中的方法来管理会话状态。下表描述了可用于管理ACID 事务的方法:

方法
说明

start_transaction

Starts a new transaction on this session. You cannot start a transaction if there's already an active transaction running in the session.

You can set transaction options including read concern, write concern, and read preference by passing a Hash as a parameter.

commit_transaction

Commits the active transaction for this session. This method returns an error if there is no active transaction for the session, the transaction was previously ended, or if there is a write conflict.

abort_transaction

Ends the active transaction for this session. This method returns an error if there is no active transaction for the session or if the transaction was committed or ended.

with_transaction

Starts a transaction prior to calling the supplied block, and commits the transaction when the block finishes. If any of the operations in the block, or the commit operation, result in a transient transaction error, the block and/or the commit will be executed again.

此示例定义了一个 run_transaction 方法,用于修改 sample_mflix数据库集合中的数据。 该代码执行以下操作:

  • 创建 Mongo::Collection 实例以访问权限moviesusers 集合。

  • 指定ACID 事务的读关注和写入关注。

  • 启动ACID 事务。

  • 将文档插入 movies集合并打印结果。

  • 更新 users集合中的文档并打印结果。

database = client.use('sample_mflix')
movies_collection = database[:movies]
users_collection = database[:users]
def run_transaction(session, movies_collection, users_collection)
transaction_options = {
read_concern: { level: "snapshot" },
write_concern: { w: "majority" }
}
session.with_transaction(transaction_options) do
# Inserts document into the "movies" collection
insert_result = movies_collection.insert_one({ name: 'The Menu', runtime: 107 }, session: session)
puts "Insert completed: #{insert_result.inspect}"
# Updates document in the "users" collection
update_result = users_collection.update_one({ name: 'Amy Phillips'}, { "$set" => { name: 'Amy Ryan' }}, session: session)
puts "Update completed: #{update_result.inspect}"
end
end
# Starts a session
session = client.start_session
begin
# Runs the transaction
run_transaction(session, movies_collection, users_collection)
puts "Transaction committed successfully."
rescue Mongo::Error::OperationFailure => e
puts "Transaction failed and was aborted. Error: #{e.message}"
ensure
session.end_session
end

注意

不支持并行操作

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

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

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

要学习;了解有关ACID compliance的更多信息,请参阅MongoDB网站上的《数据库管理系统中ACID属性指南》一文。

要了解有关插入操作的更多信息,请参阅插入文档指南。

要进一步了解本指南所提及的方法和类型,请参阅以下 API 文档:

后退

批量写入操作

在此页面上