Прервать длинную транзакцию с помощью pg-обещания
Мне нужен способ отклонить pg-обещание в этом коде:
db.tx(async t => {
var file = await t.one(`insert into ui.user_datasets_files (user_dataset_id,filename) values (${itemId},'${fileName}') RETURNING id`);
var data = rows.map(row => {
return {
user_dataset_id: itemId,
file_id: file.id,
json_data: JSON.stringify(row)
};
});
const insert = pgPromise.helpers.insert(data, dataset_data_columns);
return t.none(insert);
}).then(() => callback()).catch(err => callback(err));
эта строка занимает много времени, и пользователь может завершить соединение:
return t.none(insert);
Итак, я хочу, чтобы завершить выполнение и сделать откат внутри этого события:
req.on('close', function () {
promise.reject('Connection Closed');
});
1 ответ
Разбивайте / вставляйте через вставки, и между каждой вставкой проверяйте, нужно ли прервать транзакцию, и если да, то выдает ошибку, и транзакция завершится.
Так, например, вместо вставки 10000 строк в одну вставку, вы можете сделать 10 вставок по 1000 строк. Это будет выполняться чуть медленнее, но сделает вашу транзакцию прерываемой без большой задержки.
Вы можете разбивать данные на страницы либо через последовательность, как показано в разделе "Импорт данных", либо с помощью простого цикла, если все данные находятся в памяти.
в моем коде все строки находятся в памяти, как я могу разбить вставки?
db.tx(async t => {
while(/* there is data */) {
// get the next set of rows from memory;
const insert = pgPromise.helpers.insert(data, dataset_data_columns);
await t.none(insert)
.then(() => {
if(/* need to interrupt */) {
throw new Error('Interrupting transaction');
}
});
}
}).then().catch();