Efficiency of Promise-based parallel insert queries in MySQL falls short

I have developed a code in Node.js to execute insert queries using Promise.js but unfortunately, I am encountering an exception stating "Duplicate Primary Key" entry.

Here is the snippet of the code:

 var Promise = require("promise");
 var mySql = require("mysql");
 var _ = require("underscore");

 var connection = mySql.createConnection({
   host : "localhost",
   user : "root",
   password : "rahul",
   database : "testDb" //schema
 });

 connection.connect();

function insertDept(name){
   return new Promise(fn);

   function fn(resolve,reject){
    getMaxDept().then(function(rows){
        var deptId = rows[0]["DeptId"];
        deptId = (_.isNull(deptId) === true) ? 125 : deptId;
        var sql = "insert into departmentTbl values("+deptId+",'"+name+"')";
        console.log(sql);
        connection.query(sql,function(err,rows,fields){
            if(err){
                console.log(err);
                return reject(err);
            }else{
                return resolve(rows);
            }
        });

    }).catch(function(error){
        return reject(error);
    }); 
   }//fn            
 }//insertDept

// More code follows

The issue arises when attempting to run multiple insert queries at once due to the parallel nature of promises. In this case, the primary key constraint for the second Department's insert query fails.

To address this problem, one approach would be to utilize triggers in the database to calculate the next value of the primary key (department ID) before inserting. Alternatively, adjustments could also be made within the Node.js code itself.

Answer №1

The challenge at hand is not specific to node or JavaScript; it arises whenever any technology attempts to write concurrently to an SQL database. Generating unique IDs under such circumstances can be quite complex.

If possible, consider setting your id field in the database as AUTO_INCREMENT. This simple step can prevent many headaches in situations like the one described.

For more information on AUTO_INCREMENT, visit here.

Answer №2

Great advice regarding the AUTO_INCREMENT feature.

You may want to consider creating a promisifier for connection.query() to clean up the rest of the code.

By removing getMaxDept() and implementing a connection.queryAsync() utility, your code could look something like this:

var Promise = require("promise");
var mySql = require("mysql");

var connection = mySql.createConnection({
   host: "localhost",
   user: "root",
   password: "password123",
   database: "testDB" //schema
});

connection.connect();

// Promisifier for connection.query()
connection.queryAsync = function(sql) {
    return new Promise((resolve, reject) => {
        connection.query(sql, (err, rows, fields) => {
            if(err) { reject(err); }
            else { resolve({'rows':rows, 'fields':fields}); }
        });
    });
};

function insertDept(name) {
    var sql = "insert into departmentTable values('" +  name + "')"; // assume - verify needed
    return connection.queryAsync(sql);
}

function createDeptForAll(departments) {
    if(departments.length > 0) {
        return Promise.all(departments.map(insertDept));
    } else {
        return Promise.reject(new Error('No departments provided'));
    }
}

createDeptForAll(['Archeology', 'Anthropology']).then((results) => {
    results.forEach((result) => {
        console.log("Rows inserted: " + result.rows.affectedRows);
        connection.end();
    });
}).catch((error) => {
    console.log(error);
    connection.end();
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Express.js redirection not refreshing Jade HTML content

I'm currently facing an issue with displaying a flash message in Express.js using Jade's templating engine and connect-flash. My goal is to show an error message when a user tries to add a new User object to the database that already exists. Howe ...

utilizing jQuery to create dynamic data changes based on JSON file

<div id="rightside"> <h1>John Doe</h1> <p>1980 - 2020 <p><a href="johnswebsite.com">Visit Website</a> <p>Lorem ipsum dolor sit amet, consectetur adi ...

Why is TypeScript giving an error about an undefined object key, even though the key was assigned a value in the previous command?

type MaybeThereIsAValue = { [p: string]: string | undefined } ... let bar: MaybeThereIsAValue = {}; const key = "carpe"; bar[key] = "diem"; const why = bar[key]; // why is string | undefined I am confused as to why why is showing ...

Dynamically incorporating Angular UI Datepicker into your project

For my project, I am required to include a dynamic number of datepickers on the page. I attempted to accomplish this using the following method (Plunker): Script: var app = angular.module('plunker', ['ui.bootstrap']); app.controll ...

AngularJS Partial Views: Enhancing Your Website's User Experience

As a newcomer to the world of Angular, I am seeking guidance on a specific issue. I have encountered a one-to-many relationship scenario where one Category can have multiple Product items. The challenge lies in my layout page setup where I display various ...

Mastering the art of using res.send() in Node.js

I have been working on a project using the mongoose API with Node.js/Express. There seems to be an issue with my get request on the client side as the data is not coming through. Can someone help me figure out what's wrong? Snippet of backend app.ge ...

Displaying two distinct tables utilizing ng-repeat by employing customized directives

I'm facing an issue with a custom directive that generates tables and is appearing twice on my index page. The data for these tables comes from the $scope.globalrows variable. Even though globalrows contains 2 arrays, it always displays the second arr ...

Vue's Global mixins causing repetitive fires

In an effort to modify page titles, I have developed a mixin using document.title and global mixins. The contents of my mixin file (title.ts) are as follows: import { Vue, Component } from 'vue-property-decorator' function getTitle(vm: any): s ...

How can we dynamically navigate to the next line within the Material UI DataGrid component when space is limited?

Currently, I am working with the datagrid component from material ui. I have retrieved some data from a database and am attempting to pass it to the datagrid component. However, I have noticed that certain fields contain long strings which do not fully app ...

Strange behavior occurs when a DOCTYPE is specified in XSLT and javascript interactions

Within our XLST, we utilize "vanilla" JavaScript to manipulate certain div elements within our reports. One particular div sits in the center of the screen and overlaps all other content. The code snippet below is used to position this div when the page lo ...

PHP Temp File Not Found After AJAX File Upload

Recently, I've been researching how to upload files through AJAX using FormData and FileReader. However, I keep encountering a recurring issue. After initiating the file upload process, the file is sent to a PHP script for validation and then an atte ...

Looking for assistance with using an array in a for loop with an if-

I'm having trouble with a For loop array. I need to retrieve the data that is opposite of a given function, but when I use arr[i] != elem, it prints out the entire array. On the other hand, if I use arr[i] == elem, it gives me the array that I don&apo ...

This issue with ng-include not functioning properly in Chrome but working fine in Firefox

My code is running only in Firefox and not working in Chrome. HTML Code <div ng-controller="myController1"> Select View: <select ng-model="employeeview"> <option value="1.html">1</option> < ...

Leverage node rework CSS directly within your browser for seamless website

Looking to utilize the reworkcss/css library in the browser. Downloaded version 2.0.0 from GitHub and installed necessary packages with npm install. Attempted using requireJS, which supports processing the CommonJS Module Format by requiring index.js, bu ...

Retrieving the value of an array from a JSON data structure

I am working with the object shown below to extract the desired output. The result will be a new object that represents the final output. var data = { Customer: { Name: "emp1", Departments: [ {Departme ...

validating if Object may be either 'null' or 'undefined'

In the code snippet below, I am attempting to verify whether hostel.country.address is null: return hostel.country.address && hostel.country.address.internalEmployeeIdentifier !== null || hostel.country.address.exter ...

JQuery functions are functioning properly in Internet Explorer 10, but are encountering issues in Internet Explorer

My JavaScript function calls a jQuery function that works in IE10 but not in IE7. function test() { // Display message before calling jQuery function... alert("Before"); // Call the jQuery function... $("#boxscroll").getNiceScroll().resize(); // Display m ...

Oops! Looks like there's an unexpected error with the module 'AppRoutingModule' that was declared in the 'AppModule'. Make sure to add a @Pipe/@Directive/@Component annotation

I am trying to create a ticket, but I encountered an error. I am currently stuck in this situation and receiving the following error message: Uncaught Error: Unexpected module 'AppRoutingModule' declared by the module 'AppModule'. Plea ...

Updating or adding items to an array using underscore library

A scenario involves an object with incoming data and an array that contains saved data. The goal is to check if the "cnName" from the new data already exists in the "savedData" array. If it does, then the object in "savedData" should be replaced with the n ...

Using jQuery Ajax and PHP to retrieve data from a database based on multiple checkboxes

my code currently only selects one checkbox at a time. What I am trying to achieve is when clicking on the first checkbox, it should display a result. Then, if the second or third checkbox is clicked, all checkboxes should be submitted together to the proc ...