Một quá trình hàng loạt có thể được dừng lại


7

Có cách nào để buộc một quy trình hàng loạt dừng lại nếu một số loại lỗi xảy ra? Cụ thể, tôi có một lô bắt đầu bằng việc lưu bản ghi vào cơ sở dữ liệu. Mỗi hoạt động lô tiếp theo phụ thuộc vào cơ sở dữ liệu chèn hoạt động chính xác. Tôi muốn buộc đợt dừng lại nếu đợt đầu tiên thất bại.

Lô được gọi như thế này

$batch = array(
    'operations' => $operations,
    'finished' => 'mymodule_batch_finished',
    'title' => t('Merging records'),
    'init_message' => t('Starting processing'),
    'progress_message' => t('Processed @current out of @total.'),
    'error_message' => t('Processing has encountered an error'),
    'file' => drupal_get_path('module', 'mymodule') . '/forms/mymodule.inc'
);

đâu $operationslà mảng các hàm cần gọi.

Mỗi chức năng sử dụng PDO để cập nhật cơ sở dữ liệu. Tôi đang cố gắng tìm ra cách ngăn chặn cuộc $operationsgọi tiếp theo nếu truy vấn trong hoạt động hiện tại không thành công.

try {
  $sth = $dbh->prepare($sql);
  $sth->bindParam(':newid',$new_id,PDO::PARAM_INT);
  $sth->bindParam(':id',$id,PDO::PARAM_INT);
  if($sth->execute()) {
    $context['results']['[] = $sth->rowCount();
  }
  else {
    // TODO: stop processing due to an error
  }
}
catch(PDOException $e) {
  // TODO: stop processing due to an error
}

Nếu xảy ra lỗi, tôi muốn bỏ qua các hoạt động còn lại và đi thẳng đến mymodule_batch_finished


Làm thế nào để bạn hiện đang thực hiện tiết kiệm vào cơ sở dữ liệu? Điều gì kích hoạt quá trình hàng loạt?
Randell

thêm chi tiết để trả lời câu hỏi của bạn.
Robbert

Câu trả lời:


14

Bên trong gọi lại hàng loạt của bạn, nơi bạn làm công việc hàng loạt, bạn sẽ có thể thiết lập $context['finished']để 1, và điều đó sẽ báo hiệu cho Drupal rằng lô hoàn tất.

Vì vậy, trong trường hợp của bạn:

$error = FALSE;
try {
  $sth = $dbh->prepare($sql);
  $sth->bindParam(':newid',$new_id,PDO::PARAM_INT);
  $sth->bindParam(':id',$id,PDO::PARAM_INT);
  if($sth->execute()) {
    $context['results'][] = $sth->rowCount();
  }
  else {
    $error = TRUE;
  }
}
catch (PDOException $e) {
  $error = TRUE;
}
// If there was an error, immediately complete the batch process.
if ($error) {
  $context['finished'] = 1;
}

Và, thậm chí tốt hơn, bạn cũng có thể chuyển một thông báo lỗi $context, bạn có thể kiểm tra lại trong cuộc gọi lại đã hoàn thành, sau đó hiển thị cho người dùng cuối trong trường hợp thất bại.

Nếu bạn muốn dừng ngay lập tức xử lý bất cứ điều gì trong các cuộc gọi lại khác trong $operationsdanh sách, bạn cũng có thể cần kiểm tra biến tĩnh ở đầu mỗi cuộc gọi lại và bỏ qua cuộc gọi lại nếu trong tình trạng lỗi. Bạn có thể thử sử dụng variable_get/ variable_sethoặc một số cơ chế khác vẫn tồn tại giữa các yêu cầu trang. Đây chắc chắn sẽ là một giải pháp hackish / cuối cùng!

Xem thêm:


0

Bạn có thể thử mã dưới đây?

$result = array('status' => FALSE, 'data' => $message);
die(json_encode($result));

Điều đó sẽ chỉ cho tôi một trang lỗi. Tôi muốn bỏ qua các hoạt động còn lại và đi thẳng đếnmymodule_batch_finished
Robbert
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.