PHP mysqli连接未执行Commit或Rollback就关闭时的事务行为探究
当PHP mysqli未提交/回滚事务就关闭连接时的行为
直接给你明确结论:当你启动事务后未执行commit()或rollback()就调用$conn->close()关闭mysqli连接时,MySQL服务器会自动回滚这个未完成的事务,事务会立即终止,不会在服务器上残留,也不会阻塞其他服务的查询。
背后的核心机制
事务在MySQL里是和数据库连接强绑定的——每个连接上的事务都是独立隔离的。不管是主动调用close()关闭连接,还是连接意外断开(比如脚本超时、进程崩溃),MySQL服务器都会立刻检测到连接状态的变化,然后自动回滚该连接上所有未提交的事务。这个规则是MySQL服务器层面的默认行为,和你用的客户端库(这里是mysqli)无关,mysqli->close()只是触发了连接关闭的信号,最终的事务处理由MySQL服务器完成。
结合你的代码具体分析
看你贴的这段代码:
$conn = new mysqli('localhost', 'widget-manager', 'secret-widgets', 'widgets'); $conn->begin_transaction(MYSQLI_TRANS_START_READ_WRITE); if (false) { // 这个分支完全不会执行,没有任何commit/rollback操作 } $conn->close();
因为if(false)的分支永远不会进入,你启动了读写事务后,既没提交也没回滚就直接关闭了连接:
- 由于你没执行任何写操作(比如
UPDATE),事务本身没有修改数据,回滚操作不会有可见的影响; - 如果把
if(false)改成if(true),执行了UPDATE但没提交就关闭连接,MySQL服务器会在连接关闭时自动撤销这些修改,数据库会回到事务启动前的状态。
额外补充说明
- 完全不用担心未提交事务残留阻塞其他查询:只要连接关闭,事务就会被立即回滚,事务持有的锁(如果有的话)也会被释放,不会影响其他连接的操作;
- 即使使用持久连接(
mysqli_pconnect),当连接被复用时,新请求会在使用前自动重置会话状态,包括回滚之前未提交的事务(但还是强烈建议你在代码里显式完成commit或rollback,不要依赖这个自动行为)。
内容的提问来源于stack exchange,提问作者Samuel Ludwig
相关产品推荐
相关产品推荐

