事务是指对一个或多个实体执行的一组操作。每个事务一定是原子性的,因此事务决不会只应用一部分。事务中的所有操作要么全都应用,要么一个也不应用。
使用事务
事务会在 270 秒后或在闲置 60 秒后过期。
以下情况下操作可能失败:
- 尝试对同一个实体进行太多并发修改。
- 事务超出资源限制。
- Datastore 模式数据库遇到内部错误。
在上述所有情况下,Datastore API 都会返回错误。
事务是一项可选功能。执行数据库操作并非必须使用事务。
应用可以在单个事务中执行一组语句和操作,因此,如果任何语句或操作引发异常,系统将不会应用该组中的任何数据库操作。应用会定义要在事务中执行的操作。
以下代码段展示了如何执行事务。该代码段会将资金从一个账户转移到另一个账户。
C#
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore C# API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Go
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore Go API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Java
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore Java API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Node.js
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore Node.js API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
PHP
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore PHP API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Python
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore Python API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Ruby
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore Ruby API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
注意,为了使示例更加简洁,有时我们会在事务失败时省略 rollback
。在用于生产环境的代码中,请务必确保明确提交或回滚每个事务。
可以在事务中执行的操作
事务可以查询或查找任意数量的实体。事务的最大大小为 10 MiB。您可以使用读写事务或只读事务。
隔离和一致性
Datastore 模式数据库会强制执行可序列化隔离。不能同时修改某个事务所读取或修改的数据。
一个事务中的各查询和查找操作会看到一致的数据库状态快照。此快照一定会包含在该事务开始之前完成的所有事务和写入操作的结果。
在事务内,写入后发生的读取操作也会看到同样的快照视图。与大多数数据库不同,Datastore 模式事务中的查询和查找操作不会看到该事务中先前写入操作的结果。具体而言,如果某个实体在事务中被修改或删除,则查询或查找操作会返回该实体在事务开始时的原始版本;如果当时并不存在该实体,则系统不会返回任何内容。
事务外部的查询和查找操作也采用可序列化隔离。
并发模式
Datastore 模式的 Firestore 支持三种并发模式。并发模式是一种数据库设置,用于确定并发事务的互动方式。您可以从以下并发模式中选择一种:
悲观
读写事务使用读取者/写入者锁定来强制执行隔离和可序列化。如果两个或更多并发读写事务读取或写入相同数据,则一个事务所持有的锁会延迟另一个事务。如果您的事务不需要任何写入,您可以使用只读事务来提高性能并避免与其他事务发生争用。只读事务不需要任何锁。
Datastore 模式 Firestore 数据库默认使用悲观并发模式。
乐观
如果两个或多个并发读写事务读取或写入相同数据,则只有第一个提交其更改的事务会成功。执行写入的其他事务在提交时会失败。
使用实体组的乐观更新
仅当您的应用依赖于旧版 Cloud Datastore 的实体组事务语义时,才应使用此并发模式。此并发模式会对事务施加额外的限制:
- 事务仅限于访问 25 个实体组。
- 对实体组的写入次数限制为每秒 1 次。
- 事务中的查询必须是祖先查询。
如需移除
OPTIMISTIC_WITH_ENTITY_GROUPS
查询、事务和写入吞吐量限制,请将项目的并发模式更改为“乐观”。为确保此更改与您的项目兼容,请执行以下操作:在 Datastore 模式的 Firestore 中创建一个测试项目。
将测试项目的并发模式更改为
OPTIMISTIC
。发出 HTTP PATCH 请求,如下所示。对测试项目运行测试,以确保您的工作负载在没有实体组的情况下也能按预期运行。
查看并发模式
使用 Firestore projects.databases REST 资源查看数据库的并发模式:
curl -X GET -H "Authorization: Bearer "$(gcloud auth print-access-token) \
"https://firestore.googleapis.com/v1/projects/PROJECT_ID/databases"
更改并发模式
如需更改数据库的并发模式,请向 Firestore 的 projects.databases REST 资源发送 PATCH
请求:
curl --request PATCH \
--header "Authorization: Bearer "$(gcloud auth print-access-token) \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{"concurrencyMode":"CONCURRENCY_MODE"}' \
"https://firestore.googleapis.com/v1/projects/PROJECT_ID/databases/(default)?updateMask=concurrencyMode"
其中:
- CONCURRENCY_MODE 是
PESSIMISTIC
、OPTIMISTIC
或OPTIMISTIC_WITH_ENTITY_GROUPS
。 - PROJECT_ID 是您的 Google Cloud 项目的 ID。
事务的用途
事务的一种用途是使用新的属性值(相对于当前值)更新实体。上面的 transferFunds
示例通过从一个账户中提取资金并将资金转移到另一个账户来针对两个实体实现此过程。Datastore API 不会自动重试事务,但您可以添加自己的逻辑来进行重试,例如,用来处理因其他请求同时更新同一实体而引发的冲突。
C#
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore C# API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Go
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore Go API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Java
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore Java API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Node.js
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore Node.js API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
PHP
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore PHP API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Python
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore Python API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Ruby
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore Ruby API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
这需要使用事务,因为在此代码提取对象之后到保存修改后的对象之前的这段时段内,实体中 balance
的值可能会被其他用户更新。如果不使用事务,则用户的请求将使用另一用户进行更新前的 balance
值,且保存会覆盖新值。如果使用了事务,应用会被告知其他用户在进行更新。
事务的另一个常见用途是获取具有命名键的实体,或者如果实体尚不存在,则创建该实体(本示例基于创建实体中的 TaskList 示例):
C#
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore C# API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Go
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore Go API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Java
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore Java API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Node.js
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore Node.js API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
PHP
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore PHP API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Python
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore Python API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Ruby
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore Ruby API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
如上文所述,如果有另一位用户尝试创建或更新具有相同字符串 ID 的实体,则必须使用事务。否则,如果实体不存在并且有两位用户尝试创建该实体,则第二位创建者会在不知情的情况下覆盖第一个创建的实体。
当事务失败时,您可以让应用重试事务直到成功,或者可以将错误传递到应用的界面层,让用户处理该错误。您无需对每个事务都创建重试循环。
只读事务
最后,您可以使用事务来读取一致的数据库快照。如果您需要多次执行读取操作来呈现页面或导出必须保持一致的数据,这种方法非常实用。在这些情况下,您可以创建只读事务。
只读事务不能修改实体,因此,此类事务不会与其他任何事务发生争用,也不需要重试。如果您在某个常规的读写事务中仅执行读取操作,则该事务可能会与修改相同数据的事务之间发生争用。
C#
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore C# API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Go
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore Go API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Java
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore Java API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Node.js
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore Node.js API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
PHP
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore PHP API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Python
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore Python API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Ruby
如需了解如何安装和使用 Cloud Datastore 客户端库,请参阅 Cloud Datastore 客户端库。 如需了解详情,请参阅 Cloud Datastore Ruby API 参考文档。
如需向 Cloud Datastore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
后续步骤
- 了解查询。