Bugs item #2711298, was opened at 2009-03-25 10:39
Message generated for change (Tracker Item Submitted) made by bevz
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=462816&aid=2711298&group_id=51305

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: None
Group: None
Status: Open
Resolution: None
Priority: 5
Private: No
Submitted By: E.Bevz (bevz)
Assigned to: Nobody/Anonymous (nobody)
Summary: databaselayer: firebird transaction remains opened (wrong)

Initial Comment:
file: FirebirdPreparedStatement.cpp
method: FirebirdPreparedStatement::CreateStatement(...)
problem: if new transaction was started, and after that exception was thrown, 
transaction was not rolled back and statement was not added to statements list, 
and when database will closing, firebird exception will be thrown becouse there 
is opened transaction during database disconnection. 
I resolve this problem, but I have not ability to test my changes in HEAD 
revision of svn. There is old version of this method with my patch:

FirebirdPreparedStatement* 
FirebirdPreparedStatement::CreateStatement(isc_db_handle pDatabase, 
isc_tr_handle pTransaction, const wxString& strSQL, const wxCSConv* conv)
{
  wxArrayString Queries = ParseQueries(strSQL);

  wxArrayString::iterator start = Queries.begin();
  wxArrayString::iterator stop = Queries.end();

  FirebirdPreparedStatement *pStatement = NULL;

  if (Queries.size() < 1)
  {
    pStatement = new FirebirdPreparedStatement(pDatabase, pTransaction);
    pStatement->SetEncoding(conv);

    pStatement->SetErrorCode(DATABASE_LAYER_ERROR);
    pStatement->SetErrorMessage(_("No SQL Statements found"));

#ifndef DONT_USE_DATABASE_LAYER_EXCEPTIONS
    // If we're using exceptions, then assume that the calling program won't
    //  won't get the pStatement pointer back.  So delete is now before
    //  throwing the exception
    try
    {
      delete pStatement; //It's probably better to manually iterate over the 
list and close the statements, but for now just let close do it
    }
    catch (DatabaseLayerException& e)
    {
    }

    DatabaseLayerException error(pStatement->GetErrorCode(), 
pStatement->GetErrorMessage());
    throw error;
#endif
    return pStatement;
  }


  // Start a new transaction if appropriate
  bool startedNewTransaction = false;
  if (pTransaction == NULL)
  {
    pTransaction = 0L;
    ISC_STATUS_ARRAY status;
    int nReturn = isc_start_transaction(status, &pTransaction, 1, &pDatabase, 0 
/*tpb_length*/, NULL/*tpb*/);
    pStatement = new FirebirdPreparedStatement(pDatabase, pTransaction);
    pStatement->SetEncoding(conv);
    if (nReturn != 0)
    {
      long nSqlCode = isc_sqlcode(status);
      
pStatement->SetErrorCode(FirebirdDatabaseLayer::TranslateErrorCode(nSqlCode));
      
pStatement->SetErrorMessage(FirebirdDatabaseLayer::TranslateErrorCodeToString(nSqlCode,
 status));

#ifndef DONT_USE_DATABASE_LAYER_EXCEPTIONS
      // If we're using exceptions, then assume that the calling program won't
      //  won't get the pStatement pointer back.  So delete is now before
      //  throwing the exception
      try
      {
        delete pStatement; //It's probably better to manually iterate over the 
list and close the statements, but for now just let close do it
      }
      catch (DatabaseLayerException& e)
      {
      }

      DatabaseLayerException error(pStatement->GetErrorCode(), 
pStatement->GetErrorMessage());
      throw error;
#endif
      return pStatement;
    }
    startedNewTransaction = true;
    pStatement->SetManageTransaction(true);
  }
  else
  {
    pStatement = new FirebirdPreparedStatement(pDatabase, pTransaction);
    pStatement->SetEncoding(conv);
    pStatement->SetManageTransaction(false);
  }

  while (start != stop)
  {
    try
    {
        pStatement->AddPreparedStatement((*start));
    }
    catch(...)
    {
        if(startedNewTransaction)
            try
            {
                ISC_STATUS_ARRAY status;
                isc_rollback_transaction(status, &pTransaction);
            }
            catch(...){}
        throw;
    }

    if (pStatement->GetErrorCode() != DATABASE_LAYER_OK)
    {
      // If we're using exceptions, then assume that the calling program won't
      //  won't get the pStatement pointer back.  So delete is now before
      //  throwing the exception
#ifndef DONT_USE_DATABASE_LAYER_EXCEPTIONS
      // Set the error code and message
      DatabaseLayerException error(pStatement->GetErrorCode(), 
pStatement->GetErrorMessage());

      if(startedNewTransaction)
        try
        {
            ISC_STATUS_ARRAY status;
            isc_rollback_transaction(status, &pTransaction);
        }
        catch(...){}

      try
      {
        delete pStatement; //It's probably better to manually iterate over the 
list and close the statements, but for now just let close do it
      }
      catch (DatabaseLayerException& e)
      {
      }

      // Pass on the error
      throw error;
#endif

      return pStatement;
    }
    start++;
  }

  // Success?  Return the statement
  return pStatement;
}


With best regards,
Evgeny Bevz.

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=462816&aid=2711298&group_id=51305

------------------------------------------------------------------------------
Apps built with the Adobe(R) Flex(R) framework and Flex Builder(TM) are
powering Web 2.0 with engaging, cross-platform capabilities. Quickly and
easily build your RIAs with Flex Builder, the Eclipse(TM)based development
software that enables intelligent coding and step-through debugging.
Download the free 60 day trial. http://p.sf.net/sfu/www-adobe-com
_______________________________________________
wxCode-users mailing list
wxCode-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/wxcode-users

Reply via email to