我应该提交以下代码吗?

时间:2016-02-02 16:22:53

标签: perl postgresql dbi dbd-pg

我的代码:

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

如果我添加" $ dbh-> commit()"在第171行之后,上述警告消失了。

如果我没有添加" $ dbh-> commit()"在第171行之后,但是调用" $ hfpDbh-> disconnect();"在第140行,上述警告也消失了。

我的问题是: 警告意味着有未提交的交易?这就是我需要明确提交或断开连接来修复警告的原因。但是代码中只有SELECT操作。我缺少什么?

感谢。

2 个答案:

答案 0 :(得分:2)

  

警告意味着有未提交的交易?

由于您请求使用事务,因此存在未提交的事务,但警告实际上会通知您隐式执行了回滚。它告诉你这个,因为这可能会导致信息丢失。显然,在这种情况下,它不会导致信息丢失,但检查不够聪明,无法实现这一点。

  

我缺少什么?

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

答案 1 :(得分:2)

  • 由于您根本不修改数据库,因此无需启用事务,因此请勿将AutoCommit设置为零。这样就不需要在任何地方调用commit,并且当句柄离开dcope时数据库将自动断开连接

  • 由于您自己处理错误,因此不应将RaiseError设置为1.如果发生任何错误并且您自己的处理代码无法执行,则会导致程序立即死亡

  • 无需致电finish。它在这里不会造成任何伤害,但它也毫无意义,几乎不应该是必要的