Uploaded image for project: 'iBatis for .NET'
  1. iBatis for .NET
  2. IBATISNET-236

about dev guide (transaction handling with using syntax)

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Open
    • Trivial
    • Resolution: Unresolved
    • DataAccess 1.9 .1
    • None
    • DataAccess
    • None
    • Microsoft Windows XP Professional Service Pack 2 5.1.2600
      Microsoft .NET Framework 1.1.4322.2407
      Intel(R) Pentium(R) 4 CPU 3.00GHz
      1536 MB RAM
      sqlServer1.1 provider, oracleClient1.0 provider

    Description

      I'm using Data Access with SQL Mapper.

      You can see the example in the Data Access Guilde 1.9.1(and lower edition) Chapter5 - 5-5 - Working with Connection and Transactions - Example 5.6
      using ( IDalSession session = daoManager.OpenConnection() )
      {
      Account account = NewAccount();
      accountDao.Create(account);
      }
      using ( IDalSession session = daoManager.BeginTransaction() )
      {
      Account account = NewAccount();
      Account account2 = accountDao.GetAccountById(1);
      account2.EmailAddress = "someotherAddress@somewhere.com";
      accountDao.Create(account);
      accountDao.Update(account2);
      session.Complete(); // Commit
      }

      The example code above is not kind enough. If daoManager.OpenConnection() or daoManager.BeginTransaction() fails due to network trouble or connection timeout or something, the instance of IDalsession is null, so Dispose method is not called. This leaves SqlMapSession remain in the ISessionStore(CallContextSessionStore) and the next transactions all fails to produce an exception like below even if recovered from network trouble.

      IBatisNet.DataMapper.Exceptions.DataMapperException: SqlMap could not invoke BeginTransaction(). A Transaction is already started. Call CommitTransaction() or RollbackTransaction first.

      You can reproduce this result by writing iteration code in which "using syntax transaction" exists.

      foreach(string key in keyList)
      {
      try

      { // call transaction method which includes the code lilke Example 5.6 here }

      catch (Exception e)
      {
      Console.WriteLine(e.ToString());
      Console.WriteLine(e.StackTrace);
      // continue next
      }
      }

      My workaround so far is to call daoManager.CloseConnection() in the catch block like below and it works
      in sqlServer1.1 provider and oracleClient1.0 provider.
      try
      {
      using ( IDalSession session = daoManager.OpenConnection() )

      { Account account = NewAccount(); accountDao.Create(account); }

      }
      catch (Exception ex)
      {
      daoManager.CloseConnection();
      throw new RDBAccessException("message",ex);
      }

      try
      {
      using ( IDalSession session = daoManager.BeginTransaction() )

      { Account account = NewAccount(); Account account2 = accountDao.GetAccountById(1); account2.EmailAddress = "someotherAddress@somewhere.com"; accountDao.Create(account); accountDao.Update(account2); session.Complete(); // Commit }

      }
      catch (Exception ex)
      {
      daoManager.CloseConnection();
      throw new RDBAccessException("message",ex);
      }

      I think it will be better to describe this matter in the document.
      If you have the other better way please add it to the document.

      Thanks.

      Attachments

        Activity

          People

            Unassigned Unassigned
            noriyuki shimbo noriyuki shimbo
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated: