

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用显式事务模式进行读写
<a name="best-practices-opencypher-use-explicit-txs"></a>

在将事务与 Neptune 和 Bolt 驱动程序结合使用时，最好将读取和写入事务的访问模式显式设置为正确的设置。

## 只读事务
<a name="best-practices-opencypher-read-txs"></a>

对于只读事务，如果您在构建会话时没有传入适当的访问模式配置，则使用默认的隔离级别，即突变查询隔离。因此，对于只读事务来说，将访问模式显式设置为 `read` 非常重要。

**自动提交读取事务示例：**

```
SessionConfig sessionConfig = SessionConfig
  .builder()
  .withFetchSize(1000)
  .withDefaultAccessMode(AccessMode.READ)
  .build();
Session session = driver.session(sessionConfig);
try {
  {{(Add your application code here)}}
} catch (final Exception e) {
  throw e;
} finally {
  driver.close()
}
```

**读取事务示例：**

```
Driver driver = GraphDatabase.driver(url, auth, config);
SessionConfig sessionConfig = SessionConfig
  .builder()
  .withDefaultAccessMode(AccessMode.READ)
  .build();
driver.session(sessionConfig).readTransaction(
  new TransactionWork<List<String>>() {
    @Override
    public List<String> execute(org.neo4j.driver.Transaction tx) {
      {{(Add your application code here)}}
    }
  }
);
```

在这两种情况下，都使用 [Neptune 只读事务语义](transactions-neptune.md#transactions-neptune-read-only)实现 [`SNAPSHOT` 隔离](transactions-isolation-levels.md)。

由于只读副本仅接受只读查询，因此提交到只读副本的任何查询都在 `SNAPSHOT` 隔离语义下运行。

只读事务没有脏读或不可重复读取。

## 突变事务
<a name="best-practices-opencypher-mutation-txs"></a>

对于突变查询，有三种不同的机制可以创建写入事务，每种机制如下所示：

**隐式写入事务示例：**

```
Driver driver = GraphDatabase.driver(url, auth, config);
SessionConfig sessionConfig = SessionConfig
  .builder()
  .withDefaultAccessMode(AccessMode.WRITE)
  .build();
driver.session(sessionConfig).writeTransaction(
  new TransactionWork<List<String>>() {
    @Override
    public List<String> execute(org.neo4j.driver.Transaction tx) {
      {{(Add your application code here)}}
    }
  }
);
```

**自动提交写入事务示例：**

```
SessionConfig sessionConfig = SessionConfig
  .builder()
  .withFetchSize(1000)
  .withDefaultAccessMode(AccessMode.Write)
  .build();
Session session = driver.session(sessionConfig);
try {
  {{(Add your application code here)}}
} catch (final Exception e) {
    throw e;
} finally {
    driver.close()
}
```

**显式写入事务示例：**

```
Driver driver = GraphDatabase.driver(url, auth, config);
SessionConfig sessionConfig = SessionConfig
  .builder()
  .withFetchSize(1000)
  .withDefaultAccessMode(AccessMode.WRITE)
  .build();
Transaction beginWriteTransaction = driver.session(sessionConfig).beginTransaction();
  {{(Add your application code here)}}
beginWriteTransaction.commit();
driver.close();
```

**写入事务的隔离级别**
+ 作为突变查询的一部分进行的读取是在 `READ COMMITTED` 事务隔离下运行的。
+ 对于作为突变查询一部分进行的读取，没有脏读。
+ 在突变查询中读取时，记录和记录范围会被锁定。
+ 当突变事务已读取索引范围时，可以强力保证在读取结束之前，任何并发事务都不会修改该范围。

突变查询不是线程安全的。

有关冲突，请参阅[使用锁定等待超时解决冲突](transactions-neptune.md#transactions-neptune-conflicts)。

突变查询失败时不会自动重试。