运行事务

使用事务将相关查询组合在一起,这些查询协同工作以完成单个逻辑数据库操作。由于 Neo4j 符合 ACID 规范,因此事务内的查询将要么全部执行,要么完全不执行:你无法让事务的一部分成功而另一部分失败。

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

创建事务

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

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

请求正文可以

  • 包含一个 statements 对象,该对象包含要执行的语句列表(以下示例)

  • 包含一个 statements 对象,该对象包含一个空列表

  • 完全为空。

服务器将以新事务的位置进行响应。

示例请求

POST http://localhost: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": "http://localhost: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 http://localhost: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": "http://localhost:7474/db/neo4j/tx/50/commit",
  "transaction": {
    "expires": "Thu, 3 Aug 2023 11:45:20 GMT"
  }
}

执行多个查询

为了减少请求数量和网络开销,可以在单个请求中包含多个语句。服务器按顺序运行它们,但彼此独立,因此一个语句不能引用另一个语句中定义的变量。响应包含每个语句的结果,按顺序排列。

示例请求

POST http://localhost: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": "http://localhost: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 请求

http://localhost:7474/db/neo4j/tx/<transactionID>

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

示例请求

DELETE http://localhost: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

原子性、一致性、隔离性、持久性 (ACID) 是保证数据库事务可靠处理的属性。符合 ACID 规范的 DBMS 可确保数据库中的数据即使在发生故障的情况下也能保持准确和一致。

因果一致性

如果读取和写入查询按相同顺序被集群中的每个成员看到,则数据库就是因果一致的。这比最终一致性更强。

事务

事务是一个工作单元,要么以整体形式 提交,要么在失败时 回滚。例如银行转账:它涉及多个步骤,但它们必须 全部 成功或被恢复,以避免从一个帐户中扣款但没有添加到另一个帐户中。