2016-02-02 10 views
0

Мой код:Должен ли я зафиксировать в следующем коде?

122 # 
123 my $hfpDbh = undef; 
124 unless (
125   $hfpDbh = DBI->connect("dbi:Pg:host=....")#removed something 
128) { 
129   Log(ERROR, ""); 
130   Exit(1) 
131 } 
132 $hfpDbh->{RaiseError} = 1; 
133 $hfpDbh->{AutoCommit} = 0; 
134 
135 (my $mydata, $msg) = load_data($hfpDbh, $DatFile); 
136 unless (defined($mydata)) 
137 { 
138   Log(INFO, "Calling exit...2"); 
139 } 
140 #$hfpDbh->disconnect(); 
141 Exit(0); 
142 Log(INFO, "Calling exit...4"); 
143 
144 
145 sub load_data 
146 { 
147   my ($dbh, $DatFile) = @_; 
148   my $msg = ''; 
149   unless ($dbh) { 
150     $msg = 'cannot load data, no DB handle'; 
151     Log(ERROR, $msg); 
152   } 
153   Log(INFO, "Call load_data..."); 
154   my $q = "SELECT ip as ip FROM rules WHERE active = 'true' AND isGood = 'true';"; 
155   my $stmt = undef; 
156   unless ($stmt = $dbh->prepare($q)) { 
157     $msg = "unable to prepare SQL query: $q"; 
158     Log(ERROR, $msg); 
159   } 
160 
161   eval { $stmt->execute() }; 
162   if ([email protected]) { 
163     $msg = "failed to execute SQL query: [email protected]"; 
164     Log(ERROR, $msg); 
165   } 
166 
167   my $data = {}; 
168   while (my $row = $stmt->fetchrow_hashref()) { 
169     #Log(INFO, "testing row"); 
170   } 
171   $stmt->finish(); 
172   return $data, $msg; 
173 } 

Это предупреждение:

Issuing rollback() due to DESTROY without explicit disconnect() of DBD::Pg::db handle 

Если добавить "$ dbh-> коммит()" после того, как линия 171, выше предупреждают исчез.

Если после строки 171 не было добавлено «$ dbh-> commit()», вызывается «$ hfpDbh-> disconnect();» в строке 140 вышеупомянутое предупреждение также исчезло.

Мой вопрос: Предупреждение означает, что есть незафиксированные транзакции? Вот почему мне нужно зафиксировать или отключить явно, чтобы исправить предупреждение. Но в коде есть только операция SELECT. Что мне не хватает?

Спасибо.

+1

Ваша обработка ошибок немного неудобна. Вы уже включаете 'RaiseError', поэтому вам не следует проверять успех каждого метода вручную. 'RaiseError' генерирует исключение, если есть ошибка. Если вы хотите использовать собственный обработчик ошибок (например, для регистрации ошибок), используйте ['HandleError'] (https://metacpan.org/pod/DBI#HandleError). – ThisSuitIsBlackNot

+0

@ikegami, но disconnect() будет откатываться по незафиксированным транзакциям? Я прав? Если я не вызвал функцию load_data(), предупреждение исчезнет, ​​даже если я не отключился. – BAE

+0

Кроме того, вы не должны называть 'finish', и вы должны убедиться, что' disconnect' вызывается даже тогда, когда есть исключение или сигнал (например, с блоком 'END' и обработчиком сигналов). – ThisSuitIsBlackNot

ответ

2
  • Поскольку вы не изменяете базы данных вообще, вам не нужно активировать операции, так что не AutoCommit к нулю. Таким образом, нет необходимости вызывать commit в любом месте либо, и база данных будет автоматически отключается, когда ручка выходит из dcope

  • Поскольку вы сами обработки ошибок вы не должны установить RaiseError к 1. Это приведет к тому, программа немедленно умирает, если возникнет какая-либо ошибка, и ваш собственный код обработки не будет выполнен.

  • Нет необходимости звонить finish. Здесь не будет никакого вреда, но это также бессмысленно и почти никогда не понадобится.

+0

Если AutoCommit установлен на ноль, транзакции будут включены? и мне нужно вызвать фиксацию или откат после SELECT? – BAE

+0

@BAE: Да, установка «AutoCommit» в ноль позволяет транзакции. Но вы не изменяете базу данных, поэтому вам не нужны. При отключенных транзакциях вам не нужно ни «commit», ни «rollback» в любом месте – Borodin

2

Предупреждение означает, что существуют незафиксированные транзакции?

Существует несовершенную сделка, так как вы запросили для сделок, которые будут использоваться, но предупреждение фактически уведомляет вас о том, что откат был выполнен в неявном виде. Это говорит об этом, потому что это может привести к потере информации. Очевидно, что это не приведет к потере информации в этом случае, но проверка недостаточно умна, чтобы понять это.

Что мне не хватает?

$hfpDbh->disconnect(); или $hfpDbh->rollback();

+0

Если я не вызвал функцию load_data(), предупреждение исчезнет, ​​даже если я не отключился.Поэтому я предполагаю, что могут быть незафиксированные транзакции или что-то еще, для чего мне нужно явно называть фиксацию или отключить ... Но я смущен. – BAE

+0

Он должен понять, что в этой ситуации нет необходимости называть «откат», поэтому нет. – ikegami

+0

Я помню, что в python psql client, commit() следует вызывать, даже если выполняется только выбор. – BAE

 Смежные вопросы

  • Нет связанных вопросов^_^