2016-02-24 3 views
0

Итак, я настроил backend, который будет использоваться для перемещения физических элементов на нашем складе. База данных, на которой размещается наше программное обеспечение, является оракулом, а наша старая версия этого веб-приложения написана на PHP, который отлично работает, но имеет некоторые странные сбои и медленный, как и все ад.Node.js драйвер oracle - несколько обновлений

Бэкэнд node.js отлично работает для перемещения отдельных элементов, но как только я попытаюсь переместить ящик (который будет перемещать что-либо из 20-100 элементов), весь бэкэнд останавливается в части .commit().

Кто-нибудь знает, почему это происходит, и что я могу сделать, чтобы исправить это? Предложения по поиску и устранению неисправностей были бы очень желанными!

Код:

function move(barcode,location) { 
var p = new Promise(function(resolve,reject) { 
    console.log("Started"); 
    exports.findOwner(barcode).then(function(data) { 
    console.log("Got data"); 
    // console.log(barcode); 
    var type = data[0]; 
    var info = data[1]; 
    var sql; 
     sql = "update pitems set location = '"+location+"' where barcode = '"+barcode+"' and status = 0"; // status = 0 is goods in store. 
    ora.norway.getConnection(function(e,conn) { 

     if(e) { 
     reject({"status": 0, "msg": "Failed to get connection", "error":e}); 
     } 
     else { 
     console.log("Got connection"); 
     conn.execute(sql,[],{}, function(err,results) { 
      console.log("Executed"); 
      if(err) { 
      conn.release(); 
      reject({"status": 0, "msg": "Failed to execute sql"+sql, "error": err}); 
      } 
      else { 
      console.log("Execute was successfull"); // This is the last message logged to the console. 
      conn.commit(function(e) { 
       conn.release(function(err) { 
        console.log("Failed to release"); 
       }) 
       if(e) { 
       console.log("Failed to commit!"); 
       reject({"status": 0, "msg": "Failed to commit sql"+sql, "error": e}); 
       } 
       else { 
       console.log("derp6"); 
       resolve({"status": 1, "msg": "Relocated "+results.rowsAffected+" items."}); 
       } 
      }); 
      } 
     }); 
     } 
    }); 
    }); 
}); 
return p; 
} 

ответ

0

Я думаю, что это проблема на уровне базы данных, обновление на нескольких элементов без предоставления идентификатора может быть не разрешено.

Вы должны сделать две вещи:

1) для целей отладки, добавьте console.log (JSON.stringify (ошибка)), где вы ожидаете ошибку. Тогда вы найдете ошибку, что база данных содержит назад

2) на линии, которая говорит

   conn.release(function(err) { 
        console.log("Failed to release"); 
       }) 

Проверьте, эээ определяется:

 conn.release(function(err) { 
      if(err){ 
       console.log("Failed to release"); 
      } 
      else{console.log("conn released");} 
     }) 
+0

Добавлены ошибки, в которых он отсутствовал без каких-либо результатов. Кажется, что он никогда не попадает в раздел .commit() (или, вернее, никогда не входит в него). – yusijs

+0

Добавил autocommit в раздел, и он отлично работал. Я не большой поклонник использования autocommit, но, похоже, это единственный выбор на данный момент. – yusijs

+0

ok..если это работает для вас :). Вы получили строчную ошибку, которая возвращается сервером базы данных? –

1

Обратите внимание, что ваш код открытые для SQL-инъекций. Тем более, что вы разместили его в Интернете. ;)

Я рекомендую обновить ваше заявление, что-то вроде этого:

update pitems 
set location = :location 
where barcode = :barcode 
    and status = 0 

Затем обновите conn.execute следующим образом:

conn.execute(
    sql, 
    { 
     location: location, 
     barcode: barcode 
    }, 
    {}, 
    function(err,results) {...} 
); 

Oracle автоматически ускользает переменные связывания. Но есть еще одно преимущество в том, что вы избежите жестких парсов, когда изменяются значения переменных привязки.

Кроме того, я рад изучить проблему, с которой вы сталкиваетесь больше с фиксацией. Но это действительно помогло бы, если бы вы могли предоставить воспроизводимый тестовый пример, который я мог бы запустить на моем конце.

+0

Дэн прав: используйте привязки. Исходный PHP, возможно, был медленным, потому что переменные связывания не использовались. –

+0

Привет, Дэн, извини, что не вернусь к тебе раньше. Это отнюдь не производственный код, и, естественно, его можно избежать. Я бросил его быстро и грязно для наших дизайнеров интерфейса, чтобы издеваться над чем-то и запустить тесты. Что касается тестового примера - я запускал несколько случайных обновлений сейчас, и эта проблема возникает каждый раз, когда я запускаю более 5-10 обновлений в цикле for. Я считаю, что это из-за узла, и это асинхронный характер, и оракул в основном не способен обрабатывать все входящие запросы. На данный момент autocommit решил мою проблему (все проверки выполняются до обновлений). – yusijs

+0

rlweb, можете ли вы представить воспроизводимый тестовый пример? Я не вижу цикл обновления в вашем коде. Если вы входите в цикл, я бы рекомендовал использовать один из методов серии в асинхронной библиотеке. Если вы просто выполняете обычный цикл, выполняющий выполнение при соединении, соединение начнет действовать как устройство сериализации (оно будет стоять в очереди на выполнение). Я думаю, что все будет работать лучше/более предсказуемо, если вы сами это контролируете. Возможно, это может быть причиной проблемы. Кроме того, экспорт в середине функции, которая объявляет/возвращает обещание, очень трудно понять и следовать. –

0

Это похоже на проблему, которая у меня есть. Node.js висит при обновлении oracle db с использованием библиотеки oracledb. Похоже, когда есть 167 обновлений, они отлично работают. Программа зависает, когда у меня есть 168 обновлений. Структура программы такова:

Когда 168 записей из локального sqlite db, для каждой записи, возвращаемой как обратный вызов из sqlite: 1.) получить соединение Oracle; 2.) сделать 2 обновления для двух таблиц (одно обновление для каждой таблицы с автоматическим комментированием на последнем этапе выполнения). Все 1-е обновление завершено, но ни одно из них не может запустить второе обновление. Они просто висят там. Имея 167 записей, они будут работать до завершения.

Странная вещь, наблюдаемая, заключается в том, что ни один из 168 не мог начать работу над вторым обновлением (они закончили первое обновление), поэтому у некоторых будет возможность перейти к фиксации. Похоже, они все в какой-то очереди.

+0

Убедитесь, что у вас достаточно потоков для обработки всех подключений, иначе вы можете зайти в тупик. Bump UV_THREADPOOL_SIZE по мере необходимости. Оракулбед-док обсуждает это. –