2012-09-01 18 views
5

Tôi có một giao dịch lớn bao gồm nhận nhiều dữ liệu từ cơ sở dữ liệu A, thực hiện một số thao tác với dữ liệu này, sau đó chèn dữ liệu được thao tác vào cơ sở dữ liệu B. Tôi chỉ có quyền để chọn trong cơ sở dữ liệu A nhưng tôi có thể tạo bảng và chèn/cập nhật vv trong cơ sở dữ liệu B.xử lý các giao dịch lớn chạy dài với perl dbi

Phần thao tác và chèn được viết bằng perl và đã được sử dụng để tải dữ liệu vào cơ sở dữ liệu B từ các nguồn dữ liệu khác, yêu cầu là lấy dữ liệu cần thiết từ cơ sở dữ liệu A và sử dụng nó để khởi tạo các lớp perl. Làm thế nào tôi có thể đi về làm điều này vì vậy tôi có thể dễ dàng theo dõi và nhận từ nơi lỗi xảy ra nếu bất kỳ lỗi xảy ra trong quá trình thao tác hoặc chèn (ngắt kết nối cơ sở dữ liệu, các vấn đề với khởi tạo lớp vì giá trị không hợp lệ, đĩa cứng). thất bại vv ...)? Thực hiện giao dịch một lần dường như không phải là lựa chọn tốt vì dữ liệu số từ cơ sở dữ liệu A có nghĩa là phải mất ít nhất một ngày hoặc 2 để thao tác dữ liệu và chèn vào cơ sở dữ liệu B.

Dữ liệu từ cơ sở dữ liệu A có thể được nhóm vào khoảng 1000 nhóm bằng cách sử dụng các khóa duy nhất, với mỗi khóa có chứa 1000 hàng mỗi hàng. Một cách tôi nghĩ tôi có thể làm là viết kịch bản cho mỗi nhóm, nghĩa là tôi phải theo dõi nhóm nào đã được chèn vào cơ sở dữ liệu B. Cách duy nhất tôi có thể nghĩ để theo dõi tiến trình của nhóm nào Một cách thứ hai tôi nghĩ có thể làm là đổ tất cả các trường cần thiết để tải các lớp để thao tác và chèn vào một tệp phẳng, đọc tệp để khởi tạo các lớp và chèn vào cơ sở dữ liệu B. Điều này cũng có nghĩa là tôi đã thực hiện một số việc ghi nhật ký, nhưng nên thu hẹp nó xuống hàng chính xác trong tệp flatfile nếu có bất kỳ lỗi nào xảy ra. Kịch bản sẽ trông giống như sau:

use strict; 
use warnings; 
use DBI; 

#connect to database A 
my $dbh = DBI->connect('dbi:oracle:my_db', $user, $password, { RaiseError => 1, AutoCommit => 0 }); 

#statement to get data based on group unique key 
my $sth = $dbh->prepare($my_sql); 

my @groups; #I have a list of this already 

open my $fh, '>>', 'my_logfile' or die "can't open logfile $!"; 

eval { 
    foreach my $g (@groups){ 
     #subroutine to check if group has already been processed, either from log file or from database table 
     next if is_processed($g); 

     $sth->execute($g); 
     my $data = $sth->fetchall_arrayref; 

     #manipulate $data, then use it to load perl classes for insertion into database B 
     #. 
     #. 
     #. 
    } 
    print $fh "$g\n"; 
}; 
if ([email protected]){ 
    $dbh->rollback; 
    die "something wrong...rollback"; 
} 

Vì vậy, nếu có lỗi xảy ra, tôi có thể chạy lại tập lệnh này và bỏ qua các nhóm hoặc hàng đã được xử lý và tiếp tục.

Cả hai phương pháp này chỉ là các biến thể trên cùng một chủ đề và cả hai yêu cầu quay trở lại nơi tôi theo dõi tiến độ của mình (trong bảng hoặc tệp), bỏ qua những phương thức đã được cam kết với cơ sở dữ liệu B và xử lý dữ liệu còn lại.

Tôi chắc chắn có cách tốt hơn để làm điều này nhưng tôi đang đấu tranh để nghĩ đến các giải pháp khác. Có cách nào khác để xử lý các giao dịch lớn giữa các cơ sở dữ liệu yêu cầu thao tác dữ liệu giữa việc lấy dữ liệu ra khỏi một và chèn vào một dữ liệu khác không? Quá trình này không cần phải là tất cả trong Perl, miễn là tôi có thể tái sử dụng các lớp perl để thao tác và chèn dữ liệu vào cơ sở dữ liệu.

Trả lời

2

Xin lỗi vì đã nói như vậy nhưng tôi thực sự không thấy cách bạn có thể giải quyết vấn đề này bằng cách cắt ngắn. Đối với tôi nó có vẻ như bạn đã mặc dù khoảng cách hợp lý nhất:

  • Save the bang trong một số bảng temp/file (tôi muốn nhìn vào "perldoc -f cà vạt", hoặc sqlite) tại mỗi bước
  • lỗi Xử lý đúng cách TryCatch.pm, eval hoặc bất cứ điều gì bạn thích
  • log lỗi của bạn đúng cách, tức là có cấu trúc bản ghi bạn có thể đọc trong
  • Thêm một số "sơ yếu lý lịch" cờ để kịch bản của bạn mà đọc trong nhật ký và các dữ liệu và cố gắng trước một lần nữa

Điều này tôi có thể dọc theo dòng bạn đã suy nghĩ, nhưng như tôi đã nói, tôi không nghĩ rằng có một cách "đúng" chung để xử lý vấn đề của bạn.

+0

cảm ơn vì phản hồi, tôi chỉ muốn xem liệu có bất kỳ giải pháp thay thế nào trong trường hợp tôi đã suy nghĩ quá hẹp và bỏ lỡ điều gì đó đơn giản/rõ ràng hơn – 1stdayonthejob

Các vấn đề liên quan