WordPress 使用 wpdb 类创建的全局对象 $wpdb 实现对底层 MySQL 数据库的 DML 操作。如果你想将 WordPress 用作涉及数据库交互的开发框架,那么面临的第一个问题是 $wpdb 不支持事务,没有事务的支持,就无法保证业务的一致性。对于事务的概念这里就不做介绍了,如果你找到这篇文章,那你自然是理解的。
本插件是 wpdb 类的子类,以 wpdb 为基础实现了对事务的支持,做法是在 wpdb 类上扩展出一个子类 conn,在子类 conn 上实现对事务的支持(不受影响 wpdb 的实例 $wpdb)。为方便使用已做成插件,项目地址在这里:https://github.com/yusn/wp_conn,下载地址在这里。
使用方法
插件已定义了全局对象 $conn,在您的程序里只需要加入global $conn;
即可通过 $conn 调用那些从 wpdb 类继承来的方法,以及 $conn 自有的一些方法。换句话说在需要时你完全可以用 $conn 来替代 $wpdb。
特性介绍
这是一个试验性的项目,仅供交流。
- 仅支持 REST API;
- 自动开启事务;
- 异常自动回滚;
- 运行结束自动提交(返回 REST API 请求时);
- 支持多行插入;
- 支持自动提交模式;
- 支持手动提交;
- 支持手动回滚;
仅支持 REST API
之所以仅仅支持 REST API,是因为开启事务/自动提交/自动回滚的实现是在 REST API 提供的 filter 上实现的(与 $wpdb 不同,$conn 默认运行在手动提交模式下)。
自动开启事务
接收到 REST API 请求时自动开启事务,无需手动开启。
运行结束自动提交
API 程序运行结束,如未有异常发生,响应返回前将自动提交事务。
异常自动回滚
当 API 程序抛出异常,或返回 WP_ERROR 类实例时,将自动执行事务回滚。
若在程序抛出异常前执行了手动提交 $conn->commit();
,则提交之前的 DML 操作不会被回滚;若异常发生在手动开启事务之后,或执行$conn->commit();
之后返回 WP_ERROR,则回滚仅限于手动开启事务之后的部分。
支持自动提交模式
也可以像 $wpdb 那样,让你的代码运行在自提提交的模式下,只需要在程序中执行执行数据库操作前执行$conn->set_autocommit();
即开启自动提交模式,此后若再发生异常或错误,则无法回滚。
支持手动提交
默认情况下(未开启自动提交)在程序执行过程中,你可以在需要时随时手动提交之前的操作,只需要执行$conn->commit();
方法。执行$conn->commit();
将自动开启一个新的事务,这会让你之后的代码运行在一个新事务里,这个事务在正常响应返回前会自动被提交,若后续代码发生了异常或返回 WP_ERROR 类的实例,则这部分代码会被回滚。
开启自动提交后($conn->set_autocommit();
),若再执行手动提交($conn->commit();
),则手动提交不会生效(也不会产生新事务),因为当前已经运行在自动提交模式下,无需手动提交。
支持手动回滚
在一个事务里,你可以随时执行$conn->rollback();
方法以回滚之前的操作;若在此之前已开启了自动提交模式($conn->set_autocommit();
),则回滚操作不会生效。
支持多行插入
$wpdb 的插入方法只支持单行插入,使用$conn->insert_rows();
方法能够实现一次插入多行,该方法的返回结果是成功插入的总行数。
$res = $conn->insert_rows(
'test', // 写入的表名称
array('name'), // 写入的表字段
array('string'), // 写入字段的字段类型
array(
array('aa'), // 第一行数据
array('bb'), // 第二行数据
array('cc'), // 第三行数据
),
);
注意事项
MySQL 的 DDL 操作是无法被回滚的,即 create/drop databases,create/drop/alter table 这些命令无法被回滚,应慎重考虑在事务中包含 DDL 语句,若无法避免应考虑做相应的容错处理。