{"id":193033,"date":"2025-08-16T17:57:41","date_gmt":"2025-08-16T15:57:41","guid":{"rendered":"https:\/\/fivemx.com\/?p=193033"},"modified":"2026-08-09T12:56:02","modified_gmt":"2026-08-09T10:56:02","slug":"mysql-assincrono-para-oxmysql","status":"publish","type":"post","link":"https:\/\/rpcrate.com\/pt\/mysql-async-to-oxmysql\/","title":{"rendered":"Migrar Recursos mysql-async para oxmysql com Seguran\u00e7a"},"content":{"rendered":"<p>Mova um recurso de mysql-async para oxmysql alterando sua configura\u00e7\u00e3o de driver e revisando os par\u00e2metros de cada consulta, valor de retorno e tratamento de erros. Uma migra\u00e7\u00e3o de driver n\u00e3o exige a reescrita do seu esquema de banco de dados e n\u00e3o garante uma jogabilidade mais r\u00e1pida.<\/p>\n<h2 id=\"prepare-a-recoverable-test\">Prepare um teste recuper\u00e1vel<\/h2>\n<p>Fa\u00e7a backup do banco de dados e dos recursos correspondentes, depois trabalhe em uma c\u00f3pia isolada. Inventarie cada recurso usando mysql-async e verifique se seu framework j\u00e1 exige oxmysql. Registre a vers\u00e3o do driver instalado. Revise a <a href=\"https:\/\/github.com\/overextended\/oxmysql\">fonte e instru\u00e7\u00f5es de instala\u00e7\u00e3o do oxmysql<\/a> para essa vers\u00e3o antes de trocar os drivers.<\/p>\n<h2 id=\"load-the-connection-before-the-driver\">Carregue a conex\u00e3o antes do driver<\/h2>\n<p class=\"translation-block\">No <code>server.cfg<\/code> ativo, mantenha a configura\u00e7\u00e3o privada existente de <code>mysql_connection_string<\/code> acima de <code>ensure oxmysql<\/code>. Inicie os recursos dependentes depois. N\u00e3o publique credenciais de conex\u00e3o em logs enviados ao suporte. Remova a inicializa\u00e7\u00e3o do driver antigo somente depois de identificar e considerar todos os recursos que dependem dele.<\/p>\n<p class=\"translation-block\">Em cada recurso Lua que usa a vari\u00e1vel global <code>MySQL<\/code>, carregue a biblioteca antes dos scripts de servidor:<\/p>\n<pre data-no-translation=\"\" translate=\"no\"><code data-no-translation=\"\" translate=\"no\">server_scripts {\n    '@oxmysql\/lib\/MySQL.lua',\n    'server\/*.lua'\n}\ndependency 'oxmysql'<\/code><\/pre>\n<h2 id=\"choose-the-result-you-need\">Escolha o resultado que voc\u00ea precisa<\/h2>\n<p>Use <code data-no-translation=\"\" translate=\"no\">MySQL.query.await<\/code> para um conjunto de linhas, <code data-no-translation=\"\" translate=\"no\">MySQL.single.await<\/code> para uma linha, <code data-no-translation=\"\" translate=\"no\">MySQL.scalar.await<\/code> para um valor, <code data-no-translation=\"\" translate=\"no\">MySQL.insert.await<\/code> para um ID de inser\u00e7\u00e3o e <code data-no-translation=\"\" translate=\"no\">MySQL.update.await<\/code> para linhas afetadas. Verifique o retorno documentado para sua consulta; um resultado vazio \u00e9 diferente de um erro.<\/p>\n<p>Este exemplo executado no servidor testa uma consulta parametrizada e seu retorno sem acessar uma tabela de jogabilidade. Execute-o em um recurso depois que o oxmysql tiver iniciado:<\/p>\n<pre data-no-translation=\"\" translate=\"no\"><code data-no-translation=\"\" translate=\"no\">CreateThread(function()\n    local ok, value = pcall(function()\n        return MySQL.scalar.await('SELECT ?', { 'connection-ok' })\n    end)\n    if ok and value == 'connection-ok' then\n        print('Database parameter check passed.')\n    else\n        print('Database parameter check failed; inspect the server log privately.')\n    end\nend)<\/code><\/pre>\n<h2 id=\"review-every-converted-call\">Revise cada chamada convertida<\/h2>\n<p class=\"translation-block\">Substitua valores do usu\u00e1rio interpolados por marcadores posicionais <code>?<\/code> e uma tabela ordenada de par\u00e2metros. Identificadores de tabelas e colunas exigem uma lista fixa de permiss\u00f5es; marcadores de valores n\u00e3o podem selecionar identificadores SQL arbitr\u00e1rios.<\/p>\n<p>Await altera o fluxo de controle: use o resultado ap\u00f3s o retorno do await, trate linhas ausentes e exce\u00e7\u00f5es, e verifique se o jogador ainda est\u00e1 conectado antes de agir. Uma grava\u00e7\u00e3o SQL bem-sucedida n\u00e3o atualiza automaticamente o estado do jogador em mem\u00f3ria de um framework.<\/p>\n<h2 id=\"keep-transactions-on-one-connection\">Mantenha as transa\u00e7\u00f5es em uma conex\u00e3o<\/h2>\n<p class=\"translation-block\">Use a API de transa\u00e7\u00f5es documentada do driver para agrupar opera\u00e7\u00f5es SQL. Chamadas separadas de <code>START TRANSACTION<\/code>, consulta e <code>COMMIT<\/code> por meio de um pool de conex\u00f5es n\u00e3o garantem que todas as instru\u00e7\u00f5es usem a mesma conex\u00e3o.<\/p>\n<p>Uma transa\u00e7\u00e3o bem-sucedida significa que suas instru\u00e7\u00f5es SQL n\u00e3o falharam. Um <code data-no-translation=\"\" translate=\"no\">UPDATE<\/code> afetando zero linhas ainda pode ser SQL v\u00e1lido. A l\u00f3gica de pagamento e invent\u00e1rio deve impor explicitamente as condi\u00e7\u00f5es de neg\u00f3cios; n\u00e3o copie um trecho gen\u00e9rico de transfer\u00eancia de saldo para uma economia real.<\/p>\n<h2 id=\"verify-correctness-before-speed\">Verifique a corre\u00e7\u00e3o antes da velocidade<\/h2>\n<ol>\n<li>Procure por importa\u00e7\u00f5es, exporta\u00e7\u00f5es e padr\u00f5es de callback mysql-async restantes. Verifique se cada chamador recebe o formato que espera.<\/li>\n<li>Teste login, cria\u00e7\u00e3o de personagem, salvamento, reconex\u00e3o, invent\u00e1rio, garagens e a\u00e7\u00f5es de trabalho relevantes usando registros conhecidos. Teste banco de dados indispon\u00edvel e entrada rejeitada.<\/li>\n<li>Compare as altera\u00e7\u00f5es de linha esperadas e os saldos persistidos. Mantenha as altera\u00e7\u00f5es de esquema\/\u00edndice separadas desta migra\u00e7\u00e3o de driver.<\/li>\n<li>Para desempenho, me\u00e7a a mesma a\u00e7\u00e3o de jogo e carga de trabalho antes e depois. Investigue consultas lentas com seus planos de execu\u00e7\u00e3o; adicione \u00edndices somente ap\u00f3s inspecionar o esquema e a consulta reais.<\/li>\n<\/ol>\n<h2 id=\"release-and-rollback\">Lan\u00e7ar e reverter<\/h2>\n<p>Agende uma janela de manuten\u00e7\u00e3o, implante o conjunto de driver\/recurso correspondente e execute as mesmas verifica\u00e7\u00f5es. Mantenha o conjunto antigo privado para revers\u00e3o. Restaure um backup de banco de dados somente se necess\u00e1rio para dados ou esquema alterados, e contabilize todas as grava\u00e7\u00f5es desde esse backup. Converter texto de volta para um conjunto de caracteres menor n\u00e3o \u00e9 uma revers\u00e3o gen\u00e9rica segura.<\/p>\n<h2 id=\"reference-documentation\">Documenta\u00e7\u00e3o de refer\u00eancia<\/h2>\n<p><a href=\"https:\/\/github.com\/overextended\/oxmysql\/blob\/main\/lib\/MySQL.lua\">Fonte: overextended\/oxmysql<\/a><\/p>","protected":false},"excerpt":{"rendered":"<p>Mova um recurso de mysql-async para oxmysql alterando sua configura\u00e7\u00e3o de driver e revisando os par\u00e2metros de cada consulta, valor de retorno e tratamento de erros. Uma migra\u00e7\u00e3o de driver n\u00e3o exige a reescrita do seu esquema de banco de dados e n\u00e3o garante uma jogabilidade mais r\u00e1pida.<\/p>","protected":false},"author":1,"featured_media":193034,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2881],"tags":[2950,2944],"class_list":["post-193033","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-performance","tag-framework","tag-ox"],"_links":{"self":[{"href":"https:\/\/rpcrate.com\/pt\/wp-json\/wp\/v2\/posts\/193033","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rpcrate.com\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rpcrate.com\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rpcrate.com\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rpcrate.com\/pt\/wp-json\/wp\/v2\/comments?post=193033"}],"version-history":[{"count":0,"href":"https:\/\/rpcrate.com\/pt\/wp-json\/wp\/v2\/posts\/193033\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/rpcrate.com\/pt\/wp-json\/wp\/v2\/media\/193034"}],"wp:attachment":[{"href":"https:\/\/rpcrate.com\/pt\/wp-json\/wp\/v2\/media?parent=193033"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rpcrate.com\/pt\/wp-json\/wp\/v2\/categories?post=193033"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rpcrate.com\/pt\/wp-json\/wp\/v2\/tags?post=193033"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}