运行事务

事务性 HTTP API 已被弃用,取而代之的是 HTTP 查询 API。请参阅 查询 API → 运行事务,了解如何在查询 API 中使用事务的详细信息。

使用事务将相关查询组合在一起,以实现单个逻辑数据库操作。由于 Neo4j 符合 ACID 标准,事务 中的查询要么全部执行成功,要么全部不执行:不可能出现事务的一部分成功而另一部分失败的情况。

带有 CALL {} IN TRANSACTIONS 的 Cypher 查询不能在显式事务中执行。请改为使用 隐式事务 提交这些查询。

创建事务

要打开一个新的(显式)事务,请向以下端点发送 POST 请求

http://<host>:<port>/db/<databaseName>/tx

请求的主体可以是以下任意一种情况:

  • 包含一个 statements 对象,其中包括要执行的语句列表(如下示例)

  • 包含一个 statements 对象,其中的列表为空

  • 完全为空。

服务器将返回新事务的位置。

请求示例

POST https://:7474/db/neo4j/tx
Accept: application/json;charset=UTF-8
Content-Type: application/json
Authorization: Basic bmVvNGo6dmVyeXNlY3JldA==
{
  "statements": [
    {
      "statement": "MERGE (n:Person {name: $name, age: $age}) RETURN n",
      "parameters": {
        "name": "Patrick",
        "age": 24
      }
    }
  ]
}

示例响应

200: OK
Content-Type: application/json;charset=utf-8
{
  "results": [],
  "errors": [],
  "commit": "https://:7474/db/neo4j/tx/50/commit",
  "transaction": {
    "expires": "Thu, 3 Aug 2023 11:45:10 GMT"
  }
}

执行查询

事务打开后,您可以通过向以下端点发送更多 POST 请求来向其提交查询

http://<host>:<port>/db/<databaseName>/tx/<transactionID>

您可以在第一次请求结果的 commit 键下找到事务 ID。

请求示例

POST https://:7474/db/neo4j/tx/50
Accept: application/json;charset=UTF-8
Content-Type: application/json
Authorization: Basic bmVvNGo6dmVyeXNlY3JldA==
{
  "statements": [
    {
      "statement": "MERGE (n:Person {name: $name, age: $age}) RETURN n",
      "parameters": {
        "name": "Alice",
        "age": 42
      }
    }
  ]
}

示例响应

200: OK
Content-Type: application/json;charset=utf-8
{
  "results": [ {
    "columns": ["n"],
    "data": [ {
      "row": [ {
        "name": "Alice",
        "age": 42
      } ],
      "meta": [ {
        "id": 36,
        "elementId": "4:0ea4a108-32c5-498c-99e7-95cc67ab5f7d:36",
        "type": "node",
        "deleted": false
      } ]
    } ]
  } ],
  "errors": [],
  "commit": "https://:7474/db/neo4j/tx/50/commit",
  "transaction": {
    "expires": "Thu, 3 Aug 2023 11:45:20 GMT"
  }
}

执行多个查询

为了减少请求次数和网络开销,您可以在一次请求中包含多条语句。服务器会顺序执行这些语句,但它们相互独立,因此一条语句无法引用另一条语句中定义的变量。响应中按顺序包含每条语句的结果。

请求示例

POST https://:7474/db/neo4j/tx/50
Accept: application/json;charset=UTF-8
Content-Type: application/json
Authorization: Basic bmVvNGo6dmVyeXNlY3JldA==
{
  "statements": [
    { "statement": "RETURN 1" },
    { "statement": "RETURN 2" }
  ]
}

示例响应

200: OK
Content-Type: application/json;charset=utf-8
{
  "results": [
    {
      "columns": ["1"],
      "data": [{ "row": [1], "meta": [null] }]
    },
    {
      "columns": ["2"],
      "data": [{ "row": [2], "meta": [null] }]
    }
  ],
  "errors": [],
  "commit": "https://:7474/db/neo4j/tx/50/commit",
  "transaction": {
    "expires": "Thu, 3 Aug 2023 11:45:25 GMT"
  }
}

事务过期与保持活跃

事务在一段不活动时间后会自动过期并回滚。默认超时时间为 30 秒,但您可以在服务器配置中设置其他值(server.http.transaction_idle_timeout)。

每个响应中都会在 transaction 键下报告事务过期时间。若想在不提交新查询的情况下保持事务活跃,可向事务 URI 提交空的语句列表。

尝试向已过期的事务提交查询会导致错误

{
  "results": [],
  "errors": [ {
    "code": "Neo.ClientError.Transaction.TransactionNotFound",
    "message": "Unrecognized transaction id. Transaction may have timed out and been rolled back."
  } ]
}

如果响应中不包含 transaction 键,则对应的事务已关闭。这通常在出现错误后发生。

提交事务

要提交事务,请向以下端点发送 POST 请求

http://<host>:<port>/db/<databaseName>/tx/<transactionID>/commit

提交事务后,其更改将永久写入数据库。

请求可以选择性地包含一组最终查询,这些查询将在事务关闭前执行。

回滚事务

要回滚事务,请向以下端点发送 DELETE 请求

https://:7474/db/neo4j/tx/<transactionID>

当事务被回滚时,数据库状态会恢复到事务打开之前的状态。因此,您的查询对数据库所做的所有更改都会被丢弃。

请求示例

DELETE https://:7474/db/neo4j/tx/50
Accept: application/json;charset=UTF-8
Authorization: Basic bmVvNGo6dmVyeXNlY3JldA==

示例响应

200: OK
Content-Type: application/json;charset=utf-8
{
  "results": [],
  "errors": []
}

打开的事务上的身份验证失败

对打开的事务的请求出现身份验证错误(Neo.ClientError.Security.Unauthorized)会导致回滚。不过事务仍保持打开状态。

术语表

Aura

Aura 是 Neo4j 的全托管云服务。它提供免费和付费计划。

Cypher

Cypher 是 Neo4j 的图查询语言,允许您从数据库中检索数据。它类似于 SQL,但专门用于图数据。

ACID

原子性 (Atomicity)、一致性 (Consistency)、隔离性 (Isolation)、持久性 (Durability) (ACID) 是保证数据库事务可靠处理的属性。符合 ACID 的 DBMS 确保即使发生故障,数据库中的数据也能保持准确和一致。

因果一致性

如果集群的每个成员都以相同的顺序看到读写查询,则该数据库具有因果一致性。这比最终一致性更强。

事务

事务是一个工作单元,要么被提交,要么在失败时被回滚。例如银行转账:它涉及多个步骤,但它们必须全部成功或全部撤销,以避免钱从一个账户扣除却未存入另一个账户的情况。