Мой уровень доступа к данным выглядит следующим образом:
Connection.ts
let mysql = require('mysql');
const config = require('../../dbConfig/dbconfig');
let connectionpool = mysql.createPool({
host: config.connection.host,
user: config.connection.user,
password: config.connection.password,
database: config.connection.database,
connectionLimit: 1000,
connectTimeout: 60 * 60 * 1000,
aquireTimeout: 60 * 60 * 1000,
timeout: 60 * 60 * 1000,
});
exports.getConnection = function (callback) {
connectionpool.getConnection(callback);
};
DBfactory.ts
const _dbConnection = require('./Connection');
/**
* Factory abstraction for creating database connection
*/
class DbFactory {
static create(callback) {
let st;
const sqltranscation = require('./SqlTransaction');
_dbConnection.getConnection((err, connection) => {
if (err) {
console.log('ERROR: getConnection failed: err = ' + err);
}
st = new sqltranscation(connection);
return callback(st);
});
}
}
export const databaseFactory = DbFactory;
SQLtransaction.ts
class SqlTransaction {
connection;
constructor(connection) {
this.connection = connection;
}
query(query, params, callback) { // command
this.connection.beginTransaction((err) => {
this.connection.query(query, params, (error, result) => {
if (error) {
this.connection.rollback();
console.log(error);
return callback(null, error);
}
// console.log(result);
return callback(result, null);
});
});
}
complete() {
this.connection.commit((err) => {
if (err) {
console.log(err);
}
this.connection.release();
return err;
});
}
}
module.exports = SqlTransaction;
AddData.ts
class Data {
transaction;
constructor(st) {
this.transaction = st;
}
addData(contract, callback) {
try {
const arr = [];
// const keys = [];
// for (const k in contract[0]) {
// keys.push(k);
// }
for (let i = 0; i < contract.length; i++) {
let contractSignedDate = null;
if (contract[i].contract_signed_date !== (null || '')) {
contractSignedDate = '"' + this.dateFormat(contract[i].contract_signed_date) + '"';
} else {
contractSignedDate = null;
}
let contractExpiryDate = null;
if (contract[i].contract_expiry_date !== (null || '')) {
contractExpiryDate = '"' + this.dateFormat(contract[i].contract_expiry_date) + '"';
} else {
contractExpiryDate = null;
}
let contractImplementationDate = null;
if (contract[i].contract_implementation_date !== (null || '')) {
contractImplementationDate = '"' + this.dateFormat(contract[i].contract_implementation_date) + '"';
} else {
contractImplementationDate = null;
}
let contractTerminationDate = null;
if (contract[i].contract_termination_date !== (null || '')) {
contractTerminationDate = '"' + this.dateFormat(contract[i].contract_termination_date) + '"';
} else {
contractTerminationDate = null;
}
let notifyExpirationDays = null;
if (isNumber(contract[i].notify_expiration_days)) {
notifyExpirationDays = contract[i].voice_quota_tax;
} else {
notifyExpirationDays = null;
}
let etcApplicable;
if (contract[i].etc_applicable === 'Yes') {
etcApplicable = 1;
} else {
etcApplicable = 0;
}
const sqlQuery = '('
+ '(select id from contract_types where description = "' + contract[i].contract_type + '")' + ', '
+ '"' + contract[i].contract_reference + '"' + ','
+ '"' + contract[i].contract_name + '"' + ','
+ contractSignedDate + ', '
+ contractExpiryDate + ', '
+ contractImplementationDate + ', '
+ contractTerminationDate + ', '
+ '"' + getString(contract[i].contract_termination_notes.split('"').join('\\"')) + '"' + ', '
+ notifyExpirationDays + ', '
+ etcApplicable + ', '
+ '"' + contract[i].etc_information + '"' + ', '
+ '"' + getString(contract[i].notes.split('"').join('\\"')) + '"' + ', '
+ '(select id from vendors where company = "' + contract[i].vendor_company + '")'
+ ')';
arr.push(sqlQuery);
// console.log(sqlQuery);
}
const headers = '(contract_type_id, contract_reference, contract_name, contract_signed_date, contract_expiry_date, contract_implementation_date, contract_termination_date, contract_termination_notes ,' +
' notify_expiration_days, etc_applicable, etc_information, notes, vendor_id )';
const query = `INSERT INTO dog_and_bone.contracts ` +
headers +
` VALUES ` + arr.join(',');
// console.log(query);
const insertIds = [];
this.transaction.query(query, [],
(result, error) => {
if (error) {
return callback(null, error);
}
const length = result.affectedRows;
let insertId = result.insertId;
for (let i = 0; i < length; i++ ) {
insertIds.push(insertId++);
}
const queryArrays = [];
const keys = [];
for (const k in contract[0]) {
keys.push(k);
}
for (let i = 0; i < contract.length; i++) {
for (let j = 0; j < keys.length; j++) {
if (keys[j] === 'service_type_codes') {
// console.log(contract[i][keys[j]]);
const serviceCodes = contract[i][keys[j]].split(';');
// console.log(serviceCodes);
for (let k = 0; k < serviceCodes.length; k++) {
const sqlQueryy = `INSERT INTO dog_and_bone.contract_service_types ` + '(contract_id, service_type_id )' + ' VALUES ' + '(' +
insertIds[i] + ', ' + '(select id from service_types where code = "' + serviceCodes[k] + '")' + ')';
queryArrays.push(sqlQueryy);
}
}
if (keys[j] === 'internal_contact_ids') {
// console.log(contract[i][keys[j]]);
const internalContactIds = contract[i][keys[j]].split(';');
for (let k = 0; k < internalContactIds.length; k++) {
const sqlQueryy = `INSERT INTO dog_and_bone.contract_contacts ` + '(contract_id, contact_id, is_internal )' + ' VALUES ' + '(' +
insertIds[i] + ', ' + internalContactIds[k] + ', ' + 1 + ')';
queryArrays.push(sqlQueryy);
}
}
if (keys[j] === 'external_contact_ids') {
// console.log(contract[i][keys[j]]);
const externalContactIds = contract[i][keys[j]].split(';');
for (let k = 0; k < externalContactIds.length; k++) {
const sqlQueryy = `INSERT INTO dog_and_bone.contract_contacts ` + '(contract_id, contact_id, is_internal )' + ' VALUES ' + '(' +
insertIds[i] + ', ' + externalContactIds[k] + ', ' + 0 + ')';
queryArrays.push(sqlQueryy);
}
}
}
}
// console.log(queryArrays);
let j = 0;
for (let i = 0; i < queryArrays.length; i++) {
this.transaction.query(queryArrays[i], [],
(res, err) => {
if (err) {
return callback(null, err);
}
j++;
if (j === queryArrays.length) {
return callback(res, err);
}
});
}
// return callback(result, error);
});
} catch (e) {
return callback(null, e.message);
}
}
}
Проблема заключается в том, что я использую одно соединениевыполнить несколько операторов, но когда один из последних запросов завершается неудачно из-за ошибки, первые запросы выполняются автоматически.В основном транзакции работают не так, как ожидалось.Я что-то делаю не так?