/** * 修复锁定的事务 * 强制终止等待提交的进程 */ require('dotenv').config(); const mysql = require('mysql2/promise'); async function fixLockedTransaction() { let connection; try { connection = await mysql.createConnection({ host: process.env.DB_HOST, port: process.env.DB_PORT || 3306, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_DATABASE }); console.log('✅ 已连接到数据库'); // 1. 查找所有waiting for handler commit的进程 console.log('\n📋 查找锁定的进程...'); const [processes] = await connection.query( "SELECT Id, State, Info FROM INFORMATION_SCHEMA.PROCESSLIST WHERE State LIKE '%waiting for handler commit%'" ); console.log(`找到 ${processes.length} 个锁定的进程`); // 2. 终止所有锁定的进程 let killedCount = 0; for (const p of processes) { try { console.log(` 正在终止进程 ${p.Id}: ${p.Info?.substring(0, 100)}...`); await connection.query(`KILL ${p.Id}`); console.log(` ✅ 已终止进程 ${p.Id}`); killedCount++; } catch (err) { console.log(` ⚠️ 无法终止进程 ${p.Id}:`, err.message); } } console.log(`\n✅ 成功终止 ${killedCount} 个锁定的进程`); // 3. 清理可能重复的确认记录 console.log('\n🧹 清理可能的重复记录...'); const [duplicates] = await connection.query(` SELECT user_id, training_unit_id, COUNT(*) as count FROM training_confirmations GROUP BY user_id, training_unit_id HAVING count > 1 `); if (duplicates.length > 0) { console.log(`发现 ${duplicates.length} 组重复记录,正在清理...`); for (const dup of duplicates) { // 保留最早的记录,删除其他 await connection.query(` DELETE FROM training_confirmations WHERE user_id = ? AND training_unit_id = ? AND id NOT IN ( SELECT id FROM ( SELECT MIN(id) as id FROM training_confirmations WHERE user_id = ? AND training_unit_id = ? ) as temp ) `, [dup.user_id, dup.training_unit_id, dup.user_id, dup.training_unit_id]); console.log(` ✅ 清理了 user_id=${dup.user_id}, training_unit_id=${dup.training_unit_id} 的重复记录`); } } else { console.log('没有发现重复记录'); } console.log('\n✅ 所有操作完成!'); console.log('\n💡 现在可以重新测试预招录确认功能了'); } catch (error) { console.error('❌ 操作失败:', error.message); process.exit(1); } finally { if (connection) { await connection.end(); } } } fixLockedTransaction();