Я должен зафиксировать в следующем коде?

Мой код:

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 ( $@ ) {
163                 $msg = "failed to execute SQL query: $@";
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

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

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

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

Благодарю.

2 ответа

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

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

  • Там нет необходимости звонить finish, Это не принесет никакого вреда здесь, но это также бессмысленно и почти никогда не должно быть необходимо

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

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

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

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

Другие вопросы по тегам