当前位置: 首页> 最新文章列表> 如何在 mysqli::begin_transaction 中设置和调整事务的隔离级别?

如何在 mysqli::begin_transaction 中设置和调整事务的隔离级别?

gitbox 2025-06-17

在 PHP 中,使用 MySQL 数据库时,mysqli 扩展是最常用的与数据库进行交互的工具之一。当我们需要进行数据库操作的事务时,mysqli::begin_transaction 方法提供了一种控制事务的开始机制。然而,除了简单地开启事务之外,事务的隔离级别也是一个非常重要的考量因素,因为它直接影响到数据的读取和锁定行为。

本文将探讨如何在 mysqli::begin_transaction 中设置和调整事务的隔离级别,并讲解不同隔离级别的作用和适用场景。

什么是事务的隔离级别?

事务隔离级别定义了事务中的操作对于其他事务的可见性。不同的隔离级别决定了事务执行时,数据如何与其他并发事务进行交互。主要有以下四种事务隔离级别:

  1. READ UNCOMMITTED(读未提交):最低的隔离级别,允许事务读取其他未提交事务的数据。可能会导致脏读(Dirty Read)、不可重复读(Non-repeatable Read)和幻读(Phantom Read)。

  2. READ COMMITTED(读已提交):事务只能读取已经提交的数据。虽然避免了脏读,但仍然可能会遇到不可重复读和幻读。

  3. REPEATABLE READ(可重复读):事务在执行过程中,所有读取的行数据会被锁定,其他事务无法修改这些行。避免了脏读和不可重复读,但仍可能发生幻读。

  4. SERIALIZABLE(可串行化):最高的隔离级别,所有事务会被完全隔离,不会发生脏读、不可重复读和幻读。性能较低,但确保数据的一致性和完整性。

如何在 mysqli::begin_transaction 中设置事务的隔离级别?

mysqli 中,我们可以通过 mysqli::set_charset 方法来设置事务的隔离级别。通常,这需要在调用 begin_transaction 之前,使用 SET TRANSACTION ISOLATION LEVEL SQL 语句来设定。

以下是设置和调整事务隔离级别的步骤:

1. 创建数据库连接

首先,创建一个与 MySQL 数据库的连接:

<span><span><span class="hljs-variable">$mysqli</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">mysqli</span></span><span>(</span><span><span class="hljs-string">"localhost"</span></span><span>, </span><span><span class="hljs-string">"user"</span></span><span>, </span><span><span class="hljs-string">"password"</span></span><span>, </span><span><span class="hljs-string">"database"</span></span><span>);

</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;connect_error) {
    </span><span><span class="hljs-keyword">die</span></span><span>(</span><span><span class="hljs-string">"连接失败: "</span></span><span> . </span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;connect_error);
}
</span></span>

2. 设置事务的隔离级别

在调用 begin_transaction 之前,可以使用 SQL 语句来指定事务的隔离级别。例如,若要设置为 REPEATABLE READ 隔离级别:

<span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;</span><span><span class="hljs-title function_ invoke__">query</span></span><span>(</span><span><span class="hljs-string">"SET TRANSACTION ISOLATION LEVEL REPEATABLE READ"</span></span><span>);
</span></span>

你可以根据需要选择合适的隔离级别。

3. 开始事务

在设置了事务的隔离级别后,使用 begin_transaction 开始事务:

<span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;</span><span><span class="hljs-title function_ invoke__">begin_transaction</span></span><span>();
</span></span>

4. 执行事务操作

在事务中执行一系列的数据库操作:

<span><span><span class="hljs-keyword">try</span></span><span> {
    </span><span><span class="hljs-comment">// 执行数据库操作</span></span><span>
    </span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;</span><span><span class="hljs-title function_ invoke__">query</span></span><span>(</span><span><span class="hljs-string">"INSERT INTO table_name (column1, column2) VALUES ('value1', 'value2')"</span></span><span>);

    </span><span><span class="hljs-comment">// 提交事务</span></span><span>
    </span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;</span><span><span class="hljs-title function_ invoke__">commit</span></span><span>();
} </span><span><span class="hljs-keyword">catch</span></span><span> (</span><span><span class="hljs-built_in">Exception</span></span><span> </span><span><span class="hljs-variable">$e</span></span><span>) {
    </span><span><span class="hljs-comment">// 如果出错,回滚事务</span></span><span>
    </span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;</span><span><span class="hljs-title function_ invoke__">rollback</span></span><span>();
}
</span></span>

5. 结束事务

根据事务执行情况,可以选择提交或回滚事务:

  • 使用 $mysqli->commit() 提交事务。

  • 使用 $mysqli->rollback() 回滚事务。

示例:完整代码

<span><span><span class="hljs-meta">&lt;?php</span></span><span>
</span><span><span class="hljs-comment">// 创建数据库连接</span></span><span>
</span><span><span class="hljs-variable">$mysqli</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">mysqli</span></span><span>(</span><span><span class="hljs-string">"localhost"</span></span><span>, </span><span><span class="hljs-string">"user"</span></span><span>, </span><span><span class="hljs-string">"password"</span></span><span>, </span><span><span class="hljs-string">"database"</span></span><span>);

</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;connect_error) {
    </span><span><span class="hljs-keyword">die</span></span><span>(</span><span><span class="hljs-string">"连接失败: "</span></span><span> . </span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;connect_error);
}

</span><span><span class="hljs-comment">// 设置事务隔离级别</span></span><span>
</span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;</span><span><span class="hljs-title function_ invoke__">query</span></span><span>(</span><span><span class="hljs-string">"SET TRANSACTION ISOLATION LEVEL SERIALIZABLE"</span></span><span>);

</span><span><span class="hljs-comment">// 开始事务</span></span><span>
</span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;</span><span><span class="hljs-title function_ invoke__">begin_transaction</span></span><span>();

</span><span><span class="hljs-keyword">try</span></span><span> {
    </span><span><span class="hljs-comment">// 执行一些数据库操作</span></span><span>
    </span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;</span><span><span class="hljs-title function_ invoke__">query</span></span><span>(</span><span><span class="hljs-string">"INSERT INTO products (name, price) VALUES ('product1', 100)"</span></span><span>);
    </span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;</span><span><span class="hljs-title function_ invoke__">query</span></span><span>(</span><span><span class="hljs-string">"UPDATE products SET price = 150 WHERE name = 'product2'"</span></span><span>);

    </span><span><span class="hljs-comment">// 提交事务</span></span><span>
    </span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;</span><span><span class="hljs-title function_ invoke__">commit</span></span><span>();
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"事务提交成功!"</span></span><span>;
} </span><span><span class="hljs-keyword">catch</span></span><span> (</span><span><span class="hljs-built_in">Exception</span></span><span> </span><span><span class="hljs-variable">$e</span></span><span>) {
    </span><span><span class="hljs-comment">// 回滚事务</span></span><span>
    </span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;</span><span><span class="hljs-title function_ invoke__">rollback</span></span><span>();
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"事务回滚: "</span></span><span> . </span><span><span class="hljs-variable">$e</span></span><span>-&gt;</span><span><span class="hljs-title function_ invoke__">getMessage</span></span><span>();
}

</span><span><span class="hljs-comment">// 关闭数据库连接</span></span><span>
</span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;</span><span><span class="hljs-title function_ invoke__">close</span></span><span>();
</span><span><span class="hljs-meta">?&gt;</span></span><span>
</span></span>

隔离级别的选择

选择合适的隔离级别通常取决于业务需求和系统的并发情况。以下是一些常见场景的建议:

  • 高并发的查询操作:选择 READ COMMITTEDREPEATABLE READ,以平衡性能和数据一致性。

  • 需要严格保证数据一致性:选择 SERIALIZABLE,它会确保事务完全隔离,但性能会受到较大影响。

  • 性能要求较高的应用:在性能要求较高的情况下,可以选择 READ UNCOMMITTED,但要小心脏读问题。

总结

在 PHP 中使用 mysqli 扩展时,设置事务的隔离级别是一个非常重要的操作。通过使用 SET TRANSACTION ISOLATION LEVEL 语句,我们能够在 mysqli::begin_transaction 之前调整隔离级别,以确保事务执行的可靠性和一致性。选择合适的隔离级别对于数据库性能和数据一致性有着重要影响,因此在开发过程中应根据业务需求谨慎选择合适的事务隔离级别。