Completing a transaction with TransactionScope class

Discussion of open issues, suggestions and bugs regarding ADO.NET provider for PostgreSQL
Post Reply
JORGEMAL
Posts: 171
Joined: Thu 03 Jul 2008 23:55

Completing a transaction with TransactionScope class

Post by JORGEMAL » Fri 13 Aug 2010 23:04

I have also posted this same issue in the ASP.NET forum; if this has nothing to do with you please accept my apologies. My intention is to find out if there is any special consideration in using the TransactionScope Class with DotConnect for PostgreSQL.

I have 2 methods; one for inserting and one for deleting records. Every operation inserts or deletes several records at a time so I want to use the TransactionScope class from the SystemTransactions namespace. Also, there is a data modification method that first calls the Delete method and then the Insert method.

// --------------------------
// Insert Method
// --------------------------
protected void Insert()
{
using (TransactionScope scope1 = new TransactionScope())
{
// Code for inserting records.
scope1.Complete();
}
}

// --------------------------
// Delete Method
// --------------------------
protected void Delete()
{
using (TransactionScope scope2 = new TransactionScope())
{
// Code for deleting records.
scope2.Complete();
}
}

// --------------------------
// Update Method
// --------------------------
protected void Update()
{
using (TransactionScope scope3 = new TransactionScope())
{
Delete();
Insert();
scope3.Complete();
}
}

Methods Insert and Delete call the Complete method each one but, what happens with the Update method? It calls the Delete and Insert methods, each one calling the Complete method, and finally calls its own Complete method.

When the Insert or Delete method is called independently (not from the Update method) my code runs fine inserting or deleting correctly; but when the Update method is called an exception is thrown as follows:

---------------------------------------------------------------------------------------------------------------------
[TransactionAbortedException: The transaction has aborted.]
System.Transactions.TransactionStateAborted.EndCommit(InternalTransaction tx) +11
System.Transactions.CommittableTransaction.Commit() +228
System.Transactions.TransactionScope.InternalDispose() +328
System.Transactions.TransactionScope.Dispose() +1607
Mantenimiento_ListasPreTitulos.btnModificaLista_Click(Object sender, EventArgs e) in d:\Visual Studio 2008 Projects\lasuperlista\Mantenimiento\ListasPreTitulos.aspx.cs:340
DevExpress.Web.ASPxEditors.ASPxButton.OnClick(EventArgs e) +101
DevExpress.Web.ASPxEditors.ASPxButton.RaisePostBackEvent(String eventArgument) +413
DevExpress.Web.ASPxClasses.ASPxWebControl.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +36
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1565
---------------------------------------------------------------------------------------------------------------------

I ran my app using the debugger and chose to modify data, every instruction of both the Delete and Insert methods was executed successfully until the end of the Update's using statement was reached; the exception was thrown in the closing bracket of the using statement.

I read that the TransactionAbortedException is thrown when an operation is attempted on a transaction that has already been rolled back, or an attempt is made to commit the transaction and the transaction aborts

What is wrong?

Respectfully,
Jorge Maldonado

Settler
Posts: 19
Joined: Mon 01 Mar 2010 16:32

Post by Settler » Sun 15 Aug 2010 13:39

May be this is the same problem? Or solution will be the same?
http://www.devart.com/forums/viewtopic. ... ctionscope

Shalex
Site Admin
Posts: 9543
Joined: Thu 14 Aug 2008 12:44

Post by Shalex » Mon 16 Aug 2010 16:52

JORGEMAL, please give us the following information:
1) tell us the exact version of dotConnect for PostgreSQL your are using (x.xx.xxx);
2) modify the following sample to reproduce the error you are getting in our environment:

Code: Select all

CREATE TABLE test
(
  id serial NOT NULL,
  "name" character varying(20),
  CONSTRAINT id_pkey PRIMARY KEY (id)
);
insert into test values (1, 'asdf');
insert into test values (2, 'asdf');

Code: Select all

    class Program {
        string connStr_pg = "server=localhost;port=5432;uid=postgres;pwd=postgres;Database=postgres;schema=public;";
        PgSqlCommand cmd;
        // --------------------------
        // Insert Method
        // --------------------------
        protected void Insert_pg()
        {
            using (TransactionScope scope1 = new TransactionScope()) {
               //  Code for inserting records.
                using (PgSqlConnection conn = new PgSqlConnection(connStr_pg)) {
                    conn.Open();
                    cmd = conn.CreateCommand();
                    cmd.CommandText = "insert into test values (2, 'asdfs')";
                    cmd.ExecuteNonQuery();
                }
                scope1.Complete();
            }
        }

        // --------------------------
        // Delete Method
        // --------------------------
        protected void Delete_pg()
        {
            using (TransactionScope scope2 = new TransactionScope()) {
                // Code for deleting records.
                using (PgSqlConnection conn = new PgSqlConnection(connStr_pg)) {
                    conn.Open();
                    cmd = conn.CreateCommand();
                    cmd.CommandText = "delete from test where id = 2";
                    cmd.ExecuteNonQuery();
                }
                scope2.Complete();
            }
        }

        // --------------------------
        // Update Method
        // --------------------------
        protected void Update_pg()
        {
            using (TransactionScope scope3 = new TransactionScope()) {
                Delete_pg();
                Insert_pg();
                scope3.Complete();
            }
        } 

        static void Main(string[] args)
        {
            Program prog = new Program();
            prog.Delete_pg();
            prog.Insert_pg();
            prog.Update_pg();
        }
    }
}

JORGEMAL
Posts: 171
Joined: Thu 03 Jul 2008 23:55

Post by JORGEMAL » Mon 16 Aug 2010 22:30

Settler wrote:May be this is the same problem? Or solution will be the same?
http://www.devart.com/forums/viewtopic. ... ctionscope
Thank you (and thanks to Shalex too) for the quick reply.
I read the topic you suggested in the above link and my code worked just fine after enabling and setting the "max_prepared_transactions" parameter. Nevertheless, I noticed the following comment just below such a parameter in the postgresql.conf file:

# Note: Increasing max_prepared_transactions costs ~600 bytes of shared memory
# per transaction slot, plus lock space (see max_locks_per_transaction).
# It is not advisable to set max_prepared_transactions nonzero unless you
# actively intend to use prepared transactions.

Is there a big impact on the overall database processes?
Could there be a serious drawback when setting this parameter?
What does your experience says about it?

Best regards,
Jorge Maldonado

Shalex
Site Admin
Posts: 9543
Joined: Thu 14 Aug 2008 12:44

Post by Shalex » Tue 17 Aug 2010 12:44

We didn't investigate dependency of shared memory usage on the value of the max_prepared_transactions parameter. This is a question rather to PostgreSQL team. Please refer to PostgreSQL documentation: http://www.postgresql.org/docs/current/ ... ource.html, the max_prepared_transactions (integer) section.

alemstr
Posts: 3
Joined: Fri 10 Jun 2011 10:16

Post by alemstr » Fri 10 Jun 2011 10:49

I have done the same way, but in my case some prepared transactions are not commited (no error, no exceptions) and I can see them in pgAdmin.
So I increased max_prepared_transactions parameter and some time later I received "The transaction has aborted". Why it happening?

How I can resolve this problem.

Thanks.

Shalex
Site Admin
Posts: 9543
Joined: Thu 14 Aug 2008 12:44

Post by Shalex » Thu 16 Jun 2011 16:43

alemstr, please give us the following information:
1) the exact versions of your dotConnect for PostgreSQL (x.xx.xxx) and PostgreSQL server (x.x);
2) your call stack;
3) the value of max_prepared_transactions of your PostgreSQL server;
4) can you reproduce the problem with the code from my post (Mon Aug 16, 2010 6:52 pm)? If not, please send us a small test project with the corresponding DDL/DML script so that we can reproduce the issue in our environment.

alemstr
Posts: 3
Joined: Fri 10 Jun 2011 10:16

Post by alemstr » Mon 20 Jun 2011 11:00

1) versions of mydotConnect for PostgreSQL (5.30.165) and PostgreSQL server (9.0);
2) I can not show the call stack, because I did not have any exceptions;
3) the value of max_prepared_transactions of my PostgreSQL server is 20;
4) My problem cannot be reproduce with your code.

A small test project for reproduce this problem has been sent to email.

Send me a private message to get the test project.

Shalex
Site Admin
Posts: 9543
Joined: Thu 14 Aug 2008 12:44

Post by Shalex » Wed 22 Jun 2011 13:53

We have received your test project. We will investigate the issue and notify you about the results as soon as possible.

Shalex
Site Admin
Posts: 9543
Joined: Thu 14 Aug 2008 12:44

Re: Completing a transaction with TransactionScope class

Post by Shalex » Wed 31 Jul 2013 13:49

The problem is fixed. Please try using the latest (6.7.287) build of dotConnect for PostgreSQL and notify us about the result.

Post Reply