{"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-asincrono-a-oxmysql","status":"publish","type":"post","link":"https:\/\/rpcrate.com\/es\/mysql-async-to-oxmysql\/","title":{"rendered":"Migra recursos mysql-async a oxmysql de forma segura"},"content":{"rendered":"<p>Mueve un recurso de mysql-async a oxmysql cambiando la configuraci\u00f3n de su controlador y revisando los par\u00e1metros de cada consulta, el valor de retorno y el manejo de errores. Una migraci\u00f3n de controlador no requiere reescribir tu esquema de base de datos, y no garantiza un juego m\u00e1s r\u00e1pido.<\/p>\n<h2 id=\"prepare-a-recoverable-test\">Prepara una prueba recuperable<\/h2>\n<p>Haz una copia de seguridad de la base de datos y los recursos coincidentes, luego trabaja en una copia aislada. Inventar\u00eda cada recurso usando mysql-async y verifica si tu framework ya requiere oxmysql. Registra la versi\u00f3n del controlador instalado. Revisa el <a href=\"https:\/\/github.com\/overextended\/oxmysql\">c\u00f3digo fuente de oxmysql y las instrucciones de instalaci\u00f3n<\/a> para esa versi\u00f3n antes de cambiar de controlador.<\/p>\n<h2 id=\"load-the-connection-before-the-driver\">Carga la conexi\u00f3n antes que el controlador<\/h2>\n<p class=\"translation-block\">En el <code>server.cfg<\/code> activo, conserva el ajuste privado existente de <code>mysql_connection_string<\/code> por encima de <code>ensure oxmysql<\/code>. Inicia despu\u00e9s los recursos dependientes. No publiques credenciales de conexi\u00f3n en registros de soporte. Elimina el inicio del controlador antiguo solo despu\u00e9s de haber identificado y tenido en cuenta todos los recursos que dependen de \u00e9l.<\/p>\n<p>En cada recurso Lua que use el <code data-no-translation=\"\" translate=\"no\">MySQL<\/code> global, carga la biblioteca antes de sus 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\">Elige el resultado que necesitas<\/h2>\n<p>Usa <code data-no-translation=\"\" translate=\"no\">MySQL.query.await<\/code> para un conjunto de filas, <code data-no-translation=\"\" translate=\"no\">MySQL.single.await<\/code> para una fila, <code data-no-translation=\"\" translate=\"no\">MySQL.scalar.await<\/code> para un valor, <code data-no-translation=\"\" translate=\"no\">MySQL.insert.await<\/code> para un ID de inserci\u00f3n y <code data-no-translation=\"\" translate=\"no\">MySQL.update.await<\/code> para las filas afectadas. Verifica el retorno documentado para tu consulta; un resultado vac\u00edo es diferente de un error.<\/p>\n<p>Este ejemplo del lado del servidor prueba un viaje de ida y vuelta parametrizado sin tocar una tabla de juego. Ejec\u00fatalo desde un recurso despu\u00e9s de que oxmysql se haya 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\">Revisa cada llamada convertida<\/h2>\n<p class=\"translation-block\">Sustituye los valores interpolados del usuario por marcadores posicionales <code>?<\/code> y una tabla ordenada de par\u00e1metros. Los identificadores de tablas y columnas requieren una lista fija de valores permitidos; los marcadores de valores no pueden seleccionar identificadores SQL arbitrarios.<\/p>\n<p>Await cambia el flujo de control: usa el resultado despu\u00e9s de que await retorne, maneja las filas faltantes y las excepciones, y verifica si el jugador sigue conectado antes de actuar. Una escritura SQL exitosa no actualiza autom\u00e1ticamente el estado del jugador en memoria de un framework.<\/p>\n<h2 id=\"keep-transactions-on-one-connection\">Mant\u00e9n las transacciones en una conexi\u00f3n<\/h2>\n<p class=\"translation-block\">Utiliza la API de transacciones documentada del controlador para agrupar operaciones SQL. Las llamadas separadas de <code>START TRANSACTION<\/code>, consulta y <code>COMMIT<\/code> a trav\u00e9s de un pool de conexiones no garantizan que todas las instrucciones utilicen la misma conexi\u00f3n.<\/p>\n<p>Que una transacci\u00f3n tenga \u00e9xito significa que sus sentencias SQL no fallaron. Un <code data-no-translation=\"\" translate=\"no\">UPDATE<\/code> que afecta a cero filas a\u00fan puede ser SQL v\u00e1lido. La l\u00f3gica de pago e inventario debe aplicar las condiciones comerciales expl\u00edcitamente; no copies un fragmento gen\u00e9rico de transferencia de saldo en una econom\u00eda en vivo.<\/p>\n<h2 id=\"verify-correctness-before-speed\">Verifica la correcci\u00f3n antes que la velocidad<\/h2>\n<ol>\n<li>Busca las importaciones, exportaciones y patrones de devoluci\u00f3n de llamada restantes de mysql-async. Verifica que cada llamador reciba la forma que espera.<\/li>\n<li>Prueba el inicio de sesi\u00f3n, la creaci\u00f3n de personajes, el guardado, la reconexi\u00f3n, el inventario, los garajes y las acciones de trabajo relevantes utilizando registros conocidos. Prueba la base de datos no disponible y la entrada rechazada.<\/li>\n<li>Compara los cambios de fila esperados y los saldos persistidos. Mant\u00e9n los cambios de esquema\/\u00edndice separados de esta migraci\u00f3n de controlador.<\/li>\n<li>Para el rendimiento, mide la misma acci\u00f3n de juego y carga de trabajo antes y despu\u00e9s. Investiga las consultas lentas con sus planes de ejecuci\u00f3n; agrega \u00edndices solo despu\u00e9s de inspeccionar el esquema y la consulta reales.<\/li>\n<\/ol>\n<h2 id=\"release-and-rollback\">Lanza y revierte<\/h2>\n<p>Programa una ventana de mantenimiento, despliega el conjunto de controlador\/recurso coincidente y ejecuta las mismas comprobaciones. Mant\u00e9n el conjunto antiguo en privado para la reversi\u00f3n. Restaura una copia de seguridad de la base de datos solo si es necesario para datos o esquemas modificados, y contabiliza todas las escrituras desde esa copia de seguridad. Convertir texto de nuevo a un conjunto de caracteres m\u00e1s peque\u00f1o no es una reversi\u00f3n gen\u00e9rica segura.<\/p>\n<h2 id=\"reference-documentation\">Documentaci\u00f3n de referencia<\/h2>\n<p><a href=\"https:\/\/github.com\/overextended\/oxmysql\/blob\/main\/lib\/MySQL.lua\">Fuente: overextended\/oxmysql<\/a><\/p>","protected":false},"excerpt":{"rendered":"<p>Mueve un recurso de mysql-async a oxmysql cambiando la configuraci\u00f3n de su controlador y revisando los par\u00e1metros de cada consulta, el valor de retorno y el manejo de errores. Una migraci\u00f3n de controlador no requiere reescribir tu esquema de base de datos, y no garantiza un juego m\u00e1s r\u00e1pido.<\/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\/es\/wp-json\/wp\/v2\/posts\/193033","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rpcrate.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rpcrate.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rpcrate.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rpcrate.com\/es\/wp-json\/wp\/v2\/comments?post=193033"}],"version-history":[{"count":0,"href":"https:\/\/rpcrate.com\/es\/wp-json\/wp\/v2\/posts\/193033\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/rpcrate.com\/es\/wp-json\/wp\/v2\/media\/193034"}],"wp:attachment":[{"href":"https:\/\/rpcrate.com\/es\/wp-json\/wp\/v2\/media?parent=193033"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rpcrate.com\/es\/wp-json\/wp\/v2\/categories?post=193033"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rpcrate.com\/es\/wp-json\/wp\/v2\/tags?post=193033"}],"curies":[{"name":"gracias","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}