Re: Serializable transaction restart/re-execute

Поиск
Список
Период
Сортировка
От Filipe Pina
Тема Re: Serializable transaction restart/re-execute
Дата
Msg-id CAGQyHOz2meWLE7Vw0Tvn2Lz+9X_5EYPJp6Fuo8+uOd6g=h_KKg@mail.gmail.com
обсуждение исходный текст
Ответ на Re: Serializable transaction restart/re-execute  (Jim Nasby <Jim.Nasby@BlueTreble.com>)
Список pgsql-general
Exactly, my point was not to repeat point 4 but the whole step.

Upon serialization failure exception it would re-read data from database, perform the same something with data and save it. And point 2 is the part that fails in my "restart wrapper" function in the code I posted in stackoverflow, it doesn't read the NEW data from database, but the old one, resulting once again in serialization_failure..

We're now actually considering moving all business logic of the project to a gateway (in Django or Java) and leave postgres in SERIALIZABLE and just for data storage. We were trying to avoid that as we assume there will be some performance impact on taking away processing from within DB through the connector, but we will do some testing to be able to measure that impact



On Tue, Apr 7, 2015 at 10:43 PM, Jim Nasby <Jim.Nasby@bluetreble.com> wrote:
On 4/6/15 6:42 AM, Bill Moran wrote:
CREATE OR REPLACE FUNCTION mytest() RETURNS integer AS $$
BEGIN
     update account set balance = balance+10 where id=1 RETURNING balance;
END
$$
LANGUAGE SQL;

of course, it's unlikely that you'll ever want to wrap such a
simple query in a function, so I'm supposing that you'd want
to do something else with the old value of balance before
updating it, in which case:

CREATE OR REPLACE FUNCTION mytest() RETURNS integer AS $$
DECLARE
     cc integer;
BEGIN
     SELECT INTO cc balance FROM account WHERE id = 1 FOR UPDATE;

     RAISE NOTICE 'Balance: %', cc;
     perform pg_sleep(3);

     update account set balance = cc+10 where id=1 RETURNING balance INTO cc;

     return cc;
END
$$
LANGUAGE plpgsql;

The FOR UPDATE ensures that no other process can modify the
row while this one is sleeping.

Now, I understand that you want to don't want to do row locking,
but this is (again) an insistance on your part of trying to
force PostgreSQL to do things the way GTM did instead of
understanding the RDBMS way of doing things.

Actually, the entire point of SERIALIZABLE is to avoid the need to mess around with FOR UPDATE and similar. It's a trade-off. If you have a large application that has lots of DML paths the odds of getting explicit locking correct drop rapidly to zero. That's where SERIALIZABLE shines; you just turn it on and stop worrying about locking.

The downside of course is that you need to be ready to deal with a serialization failure.

I *think* what Fillpe was looking for is some way to have Postgres magically re-try a serialization failure. While theoretically possible (at least to a degree), that's actually a really risky thing. The whole reason you would need any of this is if you're using a pattern where you:

1 BEGIN SERIALIZABLE;
2 Get data from database
3 Do something with that data
4 Put data back in database

If you get a serialization failure, it's because someone modified the data underneath you, which means you can't simply repeat step 4, you have to ROLLBACK and go back to step 1. If you design your app with that in mind it's not a big deal. If you don't... ugh. :)
--
Jim Nasby, Data Architect, Blue Treble Consulting
Data in Trouble? Get it in Treble! http://BlueTreble.com

В списке pgsql-general по дате отправления:

Предыдущее
От: Alberto Cabello Sánchez
Дата:
Сообщение: Re: unexpected (to me) sorting order
Следующее
От: Glyn Astill
Дата:
Сообщение: Re: unexpected (to me) sorting order