From b16dabc177aecfcf9fb9fe51d1b4a9fa1d5fe180 Mon Sep 17 00:00:00 2001 From: PaPi <89279156+Mesrine67@users.noreply.github.com> Date: Fri, 27 Sep 2024 07:25:51 +0200 Subject: [PATCH] Fix job creation with full transaction for `jobs` and `job_grades` tables This patch improves the job creation process by using a complete SQL transaction to ensure that insertions into both the `jobs` and `job_grades` tables are atomic. The use of `INSERT IGNORE INTO jobs` has been corrected to avoid inconsistencies in retrieving the job ID, and all insertion steps are now part of a transaction to ensure that the job and its grades are created reliably. --- .../es_extended/server/modules/createJob.lua | 56 ++++++++----------- 1 file changed, 24 insertions(+), 32 deletions(-) diff --git a/[core]/es_extended/server/modules/createJob.lua b/[core]/es_extended/server/modules/createJob.lua index e156fa11..432d0f1b 100644 --- a/[core]/es_extended/server/modules/createJob.lua +++ b/[core]/es_extended/server/modules/createJob.lua @@ -19,18 +19,6 @@ local function doesJobAndGradesExist(name, grades) return true end -local function generateTransactionQueries(name,grades) - local queries = {} - for _, grade in ipairs(grades) do - queries[#queries+1] = { - query = 'INSERT INTO job_grades (job_name, grade, name, label, salary, skin_male, skin_female) VALUES (?, ?, ?, ?, ?, ?, ?)', - values = {name, grade.grade, grade.name, grade.label, grade.salary, '{}', '{}'} - } - end - - return queries -end - local function generateNewJobTable(name, label, grades) local job = { name = name, label = label, grades = {} } for _, v in pairs(grades) do @@ -60,43 +48,47 @@ function ESX.CreateJob(name, label, grades) if not name or name == '' then notify("ERROR",currentResourceName, 'Missing argument `name`') - return + return success end + if not label or label == '' then notify("ERROR",currentResourceName, 'Missing argument `label`') - return + return success end + if not grades or not next(grades) then notify("ERROR",currentResourceName, 'Missing argument `grades`') - return + return success end local currentJobExist = doesJobAndGradesExist(name, grades) if currentJobExist then notify("ERROR",currentResourceName, 'Job or grades already exists: `%s`', name) - return + return success end - MySQL.insert('INSERT IGNORE INTO jobs (name, label) VALUES (?, ?)', {name, label}, function(jobId) - if jobId == nil or jobId == 0 then - notify("ERROR",currentResourceName, 'Failed to insert job: `%s`', name) - return - end + local queries = { + { query = 'INSERT INTO jobs (name, label) VALUES (?, ?)', values = { name, label } } + } - local queries = generateTransactionQueries(name, grades) + for _, grade in ipairs(grades) do + queries[#queries + 1] = { + query = 'INSERT INTO job_grades (job_name, grade, name, label, salary, skin_male, skin_female) VALUES (?, ?, ?, ?, ?, ?, ?)', + values = { name, grade.grade, grade.name, grade.label, grade.salary, '{}', '{}' } + } + end - MySQL.transaction(queries, function(results) - success = results - if not results then - notify("ERROR",currentResourceName, 'Failed to insert one or more grades for job: `%s`', name) - return - end + success = exports.oxmysql:transaction_async(queries) - ESX.Jobs[name] = generateNewJobTable(name,label,grades) - notify("SUCCESS",currentResourceName, 'Job created successfully: `%s`', name) - end) - end) + if not success then + notify("ERROR", currentResourceName, 'Failed to insert one or more grades for job: `%s`', name) + return success + end + + ESX.Jobs[name] = generateNewJobTable(name, label, grades) + + notify("SUCCESS", currentResourceName, 'Job created successfully: `%s`', name) return success end