Thread: conflict txns in serialization isolation

conflict txns in serialization isolation

From
Yi LIN
Date:
I doubt if this is a bug for serialization isolation in postgresql 7.2.

I wrote a small java program to test serialization isolation level. By
definition of serialization isolation
level(http://www.postgresql.com/docs/7.2/static/xact-serializable.html),
if two concurrent txns are conflict, one of them should be aborted.
However, I found that abortion only happened when two current txns are
conflict in terms of more than 1 rows. For example,

txn1: update t_a set t_a_param2=213 where t_a_id=50 or t_a_id=51;
txn2: update t_a set t_a_param2=213 where t_a_id=50 or t_a_id=51;

In this case txn2 or txn1 will be aborted at the time of commit of the
first txn. But, if

txn1: update t_a set t_a_param2=213 where t_a_id=50;
txn2: update t_a set t_a_param2=213 where t_a_id=50;

none of them will be aborted. The last txn will be blocked until the first
txn commits and then get executed and commit.

Also select for update doesn't work as specified in
http://www.postgresql.com/docs/7.2/static/xact-serializable.html
A select for update txn won't block a conflicting update txn at all. But a
conflicting update txn does block a select for update txn.

By the way, I checked psql client. In psql client, the first conflicting
update txn will block the second concurrent conflicting update txn. But
instead of abortion, the second one will be executed after the first ones
commit.

Does anyone have the same problem as I? I am using postgresql7.2

thanks,

Yi



Re: conflict txns in serialization isolation

From
Tom Lane
Date:
Yi LIN <ylin30@cs.mcgill.ca> writes:
> Does anyone have the same problem as I? I am using postgresql7.2

Nope, not even in 7.2.

I kinda suspect that you are getting confused by JDBC autocommit
behavior and are having transactions commit when you thought they
were still open.  But without a complete example it's only speculation.

Your first gripe might also be explained by supposing that the
transactions are actually in read committed mode, and not serializable
mode at all.

            regards, tom lane

Re: conflict txns in serialization isolation

From
Yi LIN
Date:
> I kinda suspect that you are getting confused by JDBC autocommit
> behavior and are having transactions commit when you thought they
> were still open.  But without a complete example it's only speculation.
>
> Your first gripe might also be explained by supposing that the
> transactions are actually in read committed mode, and not serializable
> mode at all.

I realized those potential problems and in my codes:

db = DriverManager.getConnection(url, username, password);
db.setAutoCommit(false);
db.setTransactionIsolation(java.sql.Connection.TRANSACTION_SERIALIZABLE);

Even in Read-Committed isolation level, if version check is performed(as I
suppose postgresql7.2 will always do), one of concurrent conflicting txns
will be aborted. Read-committed is different from Snapshot in that
Read-Committed txn will read data committed before read operation starts
but snapshot txn will read data committed before the whole txn starts.

Do I correctly understand how postgresql7.2 works?

Regards,

Yi


Re: conflict txns in serialization isolation

From
Tom Lane
Date:
Yi LIN <ylin30@cs.mcgill.ca> writes:
> Read-committed is different from Snapshot in that
> Read-Committed txn will read data committed before read operation starts
> but snapshot txn will read data committed before the whole txn starts.

That's a true statement for SELECT, but a read-committed UPDATE will
in fact find and update the latest version of the row; it won't cause
changes to be lost, even if they occurred after the UPDATE statement as
a whole started.  The same is true of SELECT FOR UPDATE.

I'm not sure how that relates to your previous observations though.
Can you duplicate the apparent misbehavior in psql?  I can't.

            regards, tom lane

Re: conflict txns in serialization isolation

From
Yi LIN
Date:
Hi Tom:

> That's a true statement for SELECT, but a read-committed UPDATE will
> in fact find and update the latest version of the row; it won't cause
> changes to be lost, even if they occurred after the UPDATE statement as
> a whole started.  The same is true of SELECT FOR UPDATE.
>
> I'm not sure how that relates to your previous observations though.
> Can you duplicate the apparent misbehavior in psql?  I can't.
>

I tested psql and here is the observation I had:

For transaction isolation level = SERIALIZABLE,

If two concurrent txns update same row(or rows), one of them will be
aborted.
If one txn updates row(s) and the other concurrent txn selects the same
row(s) for update, the select txn which happened later will be blocked and
then aborted upon the time when the previous update txn commits.

For transaction isolation level = READ COMMITTED,

If two concurrent txns update same row(or rows), one of them will be
blocked before the previous txn commits, but it will commit after the
previous txn commits.
If one txn updates row(s) and the other concurrent txn selects the same
row(s) for update, the select txn which happened later will be blocked and
then select and commit upon the time when the previous update txn
commits.

These observations on psql show that postgresql7.2 is correct in terms of
SERIALIZABLE and READ COMMITTED.

However, when the JDBC program doesn't correctly work, as I stated in my
first email. i.e.,

If two concurrent txns update more than 1 same rows, one of them will be
aborted upon the time when the previous txn commits. But if they update
only 1 same row, none of them will be aborted. It doesn't matter if
transaction isolation level is set to SERIALIZABLE or READ COMMITTED.

It doesn't conform to either SERIALIZABLE or READ COMMITTED observation in
psql. So I wonder if there is a bug in JDBC driver. I set transaction
level using these APIs:

db = DriverManager.getConnection(url, username, password);
db.setAutoCommit(false);
db.setTransactionIsolation(java.sql.Connection.TRANSACTION_SERIALIZABLE);

Regards,

Yi



Re: conflict txns in serialization isolation

From
Kris Jurka
Date:

On Mon, 26 Jul 2004, Yi LIN wrote:

> db = DriverManager.getConnection(url, username, password);
> db.setAutoCommit(false);
> db.setTransactionIsolation(java.sql.Connection.TRANSACTION_SERIALIZABLE);
>

I think you want to set the transaction isolation before starting the
transaction by turning off autocommit.  Later versions of the driver make
this work correctly or throw an error on this situation, but I recall you
were using an old version.  So try reordering the last two lines.

Kris Jurka

Re: conflict txns in serialization isolation

From
Yi LIN
Date:
Hi Kris:

> > db = DriverManager.getConnection(url, username, password);
> > db.setAutoCommit(false);
> > db.setTransactionIsolation(java.sql.Connection.TRANSACTION_SERIALIZABLE);
> >
>
> I think you want to set the transaction isolation before starting the
> transaction by turning off autocommit.  Later versions of the driver make
> this work correctly or throw an error on this situation, but I recall you
> were using an old version.  So try reordering the last two lines.

Now it works correctly as psql. Thanks a lot!

Yi Lin