返回

TypeScript MySQL 事务回滚失败:问题和解决方案

mysql

在TypeScript中解决MySQL事务回滚失败问题

问题

在编写一个使用TypeScript的API函数时,我遇到了MySQL事务回滚不起作用的问题。即使在抛出错误的情况下,INSERT查询中的数据仍然存储在数据库中。

解决方案

这个问题是由于没有正确处理事务中的错误。当抛出错误时,需要显式地回滚事务。以下是如何在TypeScript中解决此问题:

try {
  await runTransaction(async query => {
    let insertResult = await sqlQuery(`
    INSERT INTO job_posts 
    (post_title,post_content,category_id,permit_type_id) 
    VALUES (?,?,?,?)`,[jobPostTile, jobPostContent, jobCategoryID, jobPermitTypeID]); //Insert new job post to `job_posts` table

    const numID : number = JSON.parse(JSON.stringify(insertResult)).insertId;

    throw new Error(); // Simulate an error

    jobLocations.forEach(async function(item, index){
      let currentLocationID = jobLocations[index];
      await sqlQuery(`
      INSERT INTO job_posts_locations
      (job_post_id, location_id)
      VALUES (?,?)`,[numID, currentLocationID]); //Insert new data to `job_posts_locations` table
    });
  });
} catch (error) {
  // Explicitly rollback the transaction on error
  con.rollback(function(err){
    if(err){
      con.release();
      reject(err);
    }
    con.release();
    reject(error);
  });
}

注意事项

除了显式回滚之外,在使用事务时还应注意以下事项:

  • 确保连接池在初始化时已正确配置为支持事务。
  • 使用 await 来正确处理异步操作。
  • 避免在事务中使用 console.log 等同步方法,因为它们可能会导致死锁。

其他提示

  • 使用调试器或日志记录工具来跟踪事务的执行。
  • 检查数据库服务器的日志以查找有关事务失败的任何附加信息。
  • 尝试使用不同的MySQL客户端或库,以排除任何潜在的客户端问题。

常见问题解答

1. 什么是MySQL事务回滚?

事务回滚是指在发生错误或失败时将数据库的状态恢复到事务开始前的状态。

2. 为什么我的事务回滚不起作用?

事务回滚不起作用的原因通常是由于没有正确处理错误。在事务中抛出错误后必须显式地回滚事务。

3. 如何显式回滚MySQL事务?

在MySQL中,可以使用 ROLLBACK 命令显式回滚事务。

4. 如何在TypeScript中使用事务回滚?

在TypeScript中,可以使用 con.rollback() 方法显式回滚事务。

5. 我应该在什么时候使用事务回滚?

应该在事务失败或抛出错误时使用事务回滚,以防止对数据库进行不一致的更新。