

# Aurora DSQL 中的 DDL 和分布式事务
<a name="working-with-ddl"></a>

数据定义语言（DDL）在 Aurora DSQL 中的行为与在 PostgreSQL 中不同。Aurora DSQL 具有一个多可用区分布式和无共享数据库层，该数据库层在多租户计算和存储实例集的基础之上构建。由于不存在单个主数据库节点或中心节点，因此数据库目录是分布式的。这样，Aurora DSQL 将 DDL 架构更改作为分布式事务进行管理。

具体而言，DDL 在 Aurora DSQL 中的行为有所不同，如下所示：

**并发控制响应**  
由于数据库目录采用分布式，Aurora DSQL 将 DDL 架构更改作为更新目录版本的分布式事务进行管理。如果会话所缓存的目录副本为较早的版本，在下次与存储交互，会话会收到带有 SQLSTATE 代码 `40001` 和 OCC 代码 `OC001` 的并发控制响应。  
例如，请考虑以下操作序列：  

1. 在会话 1 中，用户向表 `mytable` 中添加一列。这将更新目录版本。

1. 在会话 2 中，用户尝试向 `mytable` 中插入一行。此会话中仍缓存以前的目录版本。

   Aurora DSQL 返回 `SQL Error [40001]: ERROR: schema has been updated by another transaction (OC001)`。
当架构更改在受影响的事务开始之前已经完成时，也会出现 OC001 响应。Aurora DSQL 查询处理器在查询执行期间被动地发现目录更改，因此处于空闲状态的会话也有可能使用过时的目录版本执行操作。在重试时，会话刷新其目录缓存，事务通常会成功。

**DDL 和 DML 在同一个事务中**  
Aurora DSQL 中的事务只能包含一个 DDL 语句，而不能同时拥有 DDL 和 DML 语句。此限制意味着您无法在同一个事务中创建表并将数据插入到同一个表中。例如，Aurora DSQL 支持以下顺序事务。  

```
BEGIN;
  CREATE TABLE mytable (ID_col integer);
COMMIT;

BEGIN;
  INSERT into FOO VALUES (1);
COMMIT;
```
Aurora DSQL 不支持以下事务，其中同时包括 `CREATE` 和 `INSERT` 语句。  

```
BEGIN;
  CREATE TABLE FOO (ID_col integer);
  INSERT into FOO VALUES (1);
COMMIT;
```

**异步 DDL**  
在标准 PostgreSQL 中，诸如 `CREATE INDEX` 之类的 DDL 操作会锁定受影响的表，使其不可用于从其它会话中读取和写入。在 Aurora DSQL 中，这些 DDL 语句使用后台管理器异步运行。对受影响表的访问不受阻止。因此，大型表上的 DDL 可以在不停机或不影响性能的情况下运行。有关 Aurora DSQL 中异步作业管理器的更多信息，请参阅 [Aurora DSQL 中的异步索引](working-with-create-index-async.md)。