Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Firebird, InterBase Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 помогите разобраться с конфликтом в пишущих транзакциях  [new]
snakenest
Member

Откуда:
Сообщений: 23
простейший сервис на PHP, принимает запрос, читает, и пишет данные в таблицу.
Ошибка возникает когда приходит два запроса одновремено.

Вот что в логах по первому запросу:

автор
err: 23.08.2019 22:57:29 : (2)ibase_execute(): lock conflict on no wait transaction deadlock update conflicts with concurrent update concurrent transaction number is 16936694 in /srv/www/service.fitron/app/library/firebird/firebird.php at 207Array
(
[query] => update webdata set fvalue=? where idWebCome=29164 and fname=?
[param] => Array
(
[0] => Resource id #21
[1] => Новый клиент
[2] => TAG_NAME
)



вот что в логах по второму
автор
err: 23.08.2019 22:57:29 : (2)ibase_execute(): lock conflict on no wait transaction deadlock update conflicts with concurrent update concurrent transaction number is 16936694 in /srv/www/service.fitron/app/library/firebird/firebird.php at 207Array
(
[query] => update webdata set fvalue=? where idWebCome=29164 and fname=?
[param] => Array
(
[0] => Resource id #21
[1] => Хорошее
[2] => TAG_NAME
)



Вот сама функция выполняющая запрос на апдейт записи

    public static function execsql($query,$param=null)
       {
           if (!self::IsConnected()) {self::Connect(); }           
           if (self::IsConnected()) 
           {
               $tr=ibase_trans(IBASE_WRITE | IBASE_NOWAIT | IBASE_COMMITTED | IBASE_REC_VERSION ,self::$connection);                
               $res=ibase_prepare(self::$connection,$tr,$query);
               if ($param<>null)
               {
                 if (!is_array($param))
                      {
                           $ret=ibase_execute($res, $param);     
                      }
                 else
                   {
                       array_unshift($param, $res); 
                       $ret = call_user_func_array('ibase_execute', $param);   
                       
                   }        
               }
               else
                 {
                       $ret=ibase_execute($res);  
                 }
                 
                   
               ibase_commit($tr);
               return $ret;
           }
           else
           {
               return -1;
           }
       } 



Проблема, я так понимаю в этом "IBASE_WRITE | IBASE_NOWAIT | IBASE_COMMITTED | IBASE_REC_VERSION", а именно в параметрах транзакции.
IBASE_WRITE - пишущая транзакция
IBASE_NOWAIT - действия при конфликте, при данном режиме, СУБД не ждет завершения конфликтующей транзакции, а просто выдает ошибку. пробовал WAIT, но система просто ждет и так же вываливается в ошибку.
IBASE_COMMITTED - т.е. в данной транзакции все изменения, которые были подтверждены другими транзакциями, будут видны немедленно + IBASE_REC_VERSION игнорирует non-committed версии, читая последнюю committed-версию.

Подскажите, какие параметры пишущей транзакции поставить, чтобы два одновременных запроса на изменение одной и той же записи не конфликтовали друг с другом? но и видели все последние изменения commit других транзакций.
24 авг 19, 11:18    [21956895]     Ответить | Цитировать Сообщить модератору
 Re: помогите разобраться с конфликтом в пишущих транзакциях  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 48163

snakenest
Подскажите, какие параметры пишущей транзакции поставить, чтобы два одновременных запроса
на изменение одной и той же записи не конфликтовали друг с другом?

Обломись. Базу надо переводить на Оракул или переделывать логику.

Posted via ActualForum NNTP Server 1.5

24 авг 19, 12:18    [21956921]     Ответить | Цитировать Сообщить модератору
 Re: помогите разобраться с конфликтом в пишущих транзакциях  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3969
snakenest
IBASE_COMMITTED - т.е. в данной транзакции все изменения, которые были подтверждены другими транзакциями, будут видны немедленно
Не знаю, но очень сомневаюсь. Такое называется READ_COMMITED


snakenest
Подскажите, какие параметры пишущей транзакции поставить, чтобы два одновременных запроса на изменение одной и той же записи не конфликтовали друг с другом? но и видели все последние изменения commit других транзакций.

1. Не NOWAIT, а именно WAIT.
2. READ_COMMITED + REC_VERSION.
24 авг 19, 12:21    [21956923]     Ответить | Цитировать Сообщить модератору
 Re: помогите разобраться с конфликтом в пишущих транзакциях  [new]
snakenest
Member

Откуда:
Сообщений: 23
YuRock,

автор
1. Не NOWAIT, а именно WAIT.

при таком варианте, просто ждет, и все равно вылетает ошибка

автор
Не знаю, но очень сомневаюсь. Такое называется READ_COMMITED

IBASE_COMMITTED - это оно и есть
24 авг 19, 12:28    [21956930]     Ответить | Цитировать Сообщить модератору
 Re: помогите разобраться с конфликтом в пишущих транзакциях  [new]
snakenest
Member

Откуда:
Сообщений: 23
Dimitry Sibiryakov
snakenest
Подскажите, какие параметры пишущей транзакции поставить, чтобы два одновременных запроса
на изменение одной и той же записи не конфликтовали друг с другом?

Обломись. Базу надо переводить на Оракул или переделывать логику.


Oracle - хороший вариант, но лучше тогда на PostgreSQL

"или переделывать логику" ? как?
Пришли два запроса на http, одновременно, сервер запустил два потока, работают они одновременно, и оба запроса обновляют одну и туже запись.
Переписать Apache, можно, но долго. Налаживать взаимодействия между двумя процессами PHP - как?
24 авг 19, 12:35    [21956936]     Ответить | Цитировать Сообщить модератору
 Re: помогите разобраться с конфликтом в пишущих транзакциях  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 48163

snakenest
"или переделывать логику" ? как?

Убрать вот это самое "оба запроса обновляют одну и туже запись".
Ибо что-то протухло в этой консерватории.

Posted via ActualForum NNTP Server 1.5

24 авг 19, 12:44    [21956939]     Ответить | Цитировать Сообщить модератору
 Re: помогите разобраться с конфликтом в пишущих транзакциях  [new]
snakenest
Member

Откуда:
Сообщений: 23
Dimitry Sibiryakov
snakenest
"или переделывать логику" ? как?

Убрать вот это самое "оба запроса обновляют одну и туже запись".
Ибо что-то протухло в этой консерватории.


т.е. выполнение одновременного Update одной записи - для firebird это невозможно ни при каких обстоятельствах ?
24 авг 19, 12:55    [21956941]     Ответить | Цитировать Сообщить модератору
 Re: помогите разобраться с конфликтом в пишущих транзакциях  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 48163

snakenest
выполнение одновременного Update одной записи - для firebird это невозможно ни при каких
обстоятельствах ?

ДА!

Posted via ActualForum NNTP Server 1.5

24 авг 19, 13:07    [21956943]     Ответить | Цитировать Сообщить модератору
 Re: помогите разобраться с конфликтом в пишущих транзакциях  [new]
hvlad
Member

Откуда:
Сообщений: 10531
snakenest,

"логи" указывают на одну и ту же тр-цию конкурента. Т.е. либо у тебя 3 писателя, либо ты не те логи показываешь.

Далее, в запросе два маркера пар-ров, в логе видно что массив пар-ров из 3-х эл-тов.

И основной вопрос - ты уверен, что второй писатель может забить на то, что написал первый ?
Понятие lost update тебе знакомо ?

Обработка конфликта обновления обычно состоит из :
- откат тр-ции
- старт новой тр-ции
- перечитывание записи
- попытка апдейта
- проверка ошибки, коммит или всё сначала

Это оптимистичный подход, когда конфликты не часто случаются.
Некоторые СУБД в некоторых (не всех!) случаях применяют этот алгоритм самостоятельно.

Можно применить пессимистичный подход - заблокировать запись (select with lock в wait тр-ции) и потом её обновлять.
24 авг 19, 13:29    [21956948]     Ответить | Цитировать Сообщить модератору
 Re: помогите разобраться с конфликтом в пишущих транзакциях  [new]
snakenest
Member

Откуда:
Сообщений: 23
hvlad
snakenest,

"логи" указывают на одну и ту же тр-цию конкурента. Т.е. либо у тебя 3 писателя, либо ты не те логи показываешь.

Далее, в запросе два маркера пар-ров, в логе видно что массив пар-ров из 3-х эл-тов.

И основной вопрос - ты уверен, что второй писатель может забить на то, что написал первый ?
Понятие lost update тебе знакомо ?

Обработка конфликта обновления обычно состоит из :
- откат тр-ции
- старт новой тр-ции
- перечитывание записи
- попытка апдейта
- проверка ошибки, коммит или всё сначала

Это оптимистичный подход, когда конфликты не часто случаются.
Некоторые СУБД в некоторых (не всех!) случаях применяют этот алгоритм самостоятельно.

Можно применить пессимистичный подход - заблокировать запись (select with lock в wait тр-ции) и потом её обновлять.


Да, получается три одновременно пришедших запроса "терзают" одну и туже запись. Первый выполнился без ошибок и в логах чисто, два оставшихся выполнились с ошибкой.

Три параметра, это особенности этого вызова:

array_unshift($param, $res); 
$ret = call_user_func_array('ibase_execute', $param);


первый параметр это ссылка на ресурс с транзакцией.


hvlad
И основной вопрос - ты уверен, что второй писатель может забить на то, что написал первый ?

Да.
И поэтому я решил проблему изменив запрос на
"update webdata set fvalue=? where idWebCome=29164 and fname=? and fvalue is null"
тогда при срабатывании первого апдейта, остальные просто не могу обновить так как не срабатывает условие.

Но тут вопрос не в конкретном этом запросе. А именно, какие параметры пишущей транзакции позволят избежать блокировки при одновременном изменении одной и тойже записи.
Не ужели такое невозможно в Firebird?
Ведь он выдает deadlock, т.е. перед тем как произвести действия, проверяет и видит что прямо вот сейчас она уже меняется. Т.е. нельзя не выдавать deadlock, а просто поставить транзакцию в очередь и дождавшись окончания первой выполнить следующую?

По логике, так работать должен WAIT, но по факту это просто зависание и выдача того же deadlock только чуть позже, и при этом транзакции которая мешала, уже нет, она уже завершилась!
24 авг 19, 13:55    [21956955]     Ответить | Цитировать Сообщить модератору
 Re: помогите разобраться с конфликтом в пишущих транзакциях  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 48163

snakenest
hvlad
И основной вопрос - ты уверен, что второй писатель может забить на то, что написал первый
?

Да.

Значит и первый может забить на то, что напишет второй. Так в чём проблема-то? Не прошёл
update, так не прошёл. Какие именно данные будут в таблице - твоей задаче без разницы.

Posted via ActualForum NNTP Server 1.5

24 авг 19, 13:57    [21956957]     Ответить | Цитировать Сообщить модератору
 Re: помогите разобраться с конфликтом в пишущих транзакциях  [new]
hvlad
Member

Откуда:
Сообщений: 10531
snakenest
hvlad
И основной вопрос - ты уверен, что второй писатель может забить на то, что написал первый ?

Да.
Ответ не правильный, думай ещё.
24 авг 19, 14:48    [21956964]     Ответить | Цитировать Сообщить модератору
 Re: помогите разобраться с конфликтом в пишущих транзакциях  [new]
kdv
Member

Откуда: iBase.ru
Сообщений: 28117
snakenest
т.е. выполнение одновременного Update одной записи - для firebird это невозможно ни при каких обстоятельствах ?

это нормально для любой СУБД.
24 авг 19, 15:40    [21956975]     Ответить | Цитировать Сообщить модератору
 Re: помогите разобраться с конфликтом в пишущих транзакциях  [new]
Дегтярев Евгений
Member

Откуда: Барнаул
Сообщений: 1642
snakenest,

не плохо бы
- при ошибке ibase_execute откатывать транзакцию
- проверять результат ibase_commit
- познакомиться с PSR-1, PSR-2
24 авг 19, 19:22    [21957023]     Ответить | Цитировать Сообщить модератору
 Re: помогите разобраться с конфликтом в пишущих транзакциях  [new]
bsv9
Member

Откуда:
Сообщений: 33
Транзакции с параметрами READ WRITE READ COMMITTED NO RECORD_VERSION
WAIT работают без блокировок, ожидая освобождение и перезаписывая данные друг друга.
Источник.
26 авг 19, 07:35    [21957445]     Ответить | Цитировать Сообщить модератору
 Re: помогите разобраться с конфликтом в пишущих транзакциях  [new]
Ivan_Pisarevsky
Member

Откуда: НН
Сообщений: 8347
Дело не в транзакциях, дело в консерватории. Ни оракл, ни потгрес тут не поможет. Без выкидывания апдейтов этот паровоз с места не сдвинется.
26 авг 19, 11:04    [21957522]     Ответить | Цитировать Сообщить модератору
 Re: помогите разобраться с конфликтом в пишущих транзакциях  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 48163

bsv9
Транзакции с параметрами READ WRITE READ COMMITTED NO RECORD_VERSION
WAIT работают без блокировок, ожидая освобождение и перезаписывая данные друг друга.

Источник несколько преувеличивает. Это работает для двух транзакций. На трёх, как у
аффтара, получится тот же облом.

Posted via ActualForum NNTP Server 1.5

26 авг 19, 12:23    [21957578]     Ответить | Цитировать Сообщить модератору
 Re: помогите разобраться с конфликтом в пишущих транзакциях  [new]
Arioch
Member

Откуда:
Сообщений: 10967
Dimitry Sibiryakov
Значит и первый может забить на то, что напишет второй. Так в чём проблема-то?


вот-вот.

как вариант - сделать обновление данных тут через SP либо EB, которые будут дёргать "in autonomous transaction".

а обновятся данные по факту или нет - всем пофигу, иногда будут обновляться.
26 авг 19, 16:36    [21957757]     Ответить | Цитировать Сообщить модератору
 Re: помогите разобраться с конфликтом в пишущих транзакциях  [new]
Ivan_Pisarevsky
Member

Откуда: НН
Сообщений: 8347
Arioch
а обновятся данные по факту или нет - всем пофигу
Зачем тогда вообще обновлять?
26 авг 19, 16:44    [21957765]     Ответить | Цитировать Сообщить модератору
 Re: помогите разобраться с конфликтом в пишущих транзакциях  [new]
Arioch
Member

Откуда:
Сообщений: 10967
Ivan_Pisarevsky,

а вот не знаю....

но предположить могу

допустим, задача - примерно как пользовательский форум.
или онлайн магазин.

где какой-то аггрегат (количество постов, остаток SKU) изменяется несколько раз в секунду.

посетителя сайта - не игроки на бирже, они в тысячных долях секунды не оперируют.
для них - корректность агрегата на последние плюс минус 60 секунд - достаточная точность
26 авг 19, 17:08    [21957783]     Ответить | Цитировать Сообщить модератору
 Re: помогите разобраться с конфликтом в пишущих транзакциях  [new]
kdv
Member

Откуда: iBase.ru
Сообщений: 28117
Arioch
допустим, задача - примерно как пользовательский форум.
или онлайн магазин.

тогда поменять FB на MySQL без транзакций. Пусть они переписывают любые изменения как попало (как в dbf).
26 авг 19, 18:49    [21957854]     Ответить | Цитировать Сообщить модератору
 Re: помогите разобраться с конфликтом в пишущих транзакциях  [new]
Arioch
Member

Откуда:
Сообщений: 10967
kdv,

а он уже с транзакциями, это он в 3-й версии был такой, сейчас он менее удивительный
26 авг 19, 18:52    [21957855]     Ответить | Цитировать Сообщить модератору
 Re: помогите разобраться с конфликтом в пишущих транзакциях  [new]
Симонов Денис
Member

Откуда: Рязань
Сообщений: 9831
Arioch,

без транзакций MySQL и сейчас есть. Там от движка зависит. Хотя сейчас по умолчанию транзакционный движок, но можно выбрать и другой.
26 авг 19, 19:26    [21957876]     Ответить | Цитировать Сообщить модератору
 Re: помогите разобраться с конфликтом в пишущих транзакциях  [new]
H5N1
Member

Откуда: Yo.! из "Сравнения субд"
Сообщений: 218
Arioch
а он уже с транзакциями, это он в 3-й версии был такой, сейчас он менее удивительный


в 3й версии там уже все было на порядок два выше интербейза. и innodb енжин был, с его полноценными undo и redo логами, с нормальным консистентным чтением на read comitted, единым кешем и без сборки мусора.
27 авг 19, 11:41    [21958177]     Ответить | Цитировать Сообщить модератору
 Re: помогите разобраться с конфликтом в пишущих транзакциях  [new]
Мимопроходящий
Member

Откуда: бурятский тундрюк, эсквайр
Сообщений: 30321

йо, ты логин свой просрал что ле?

Posted via ActualForum NNTP Server 1.5

27 авг 19, 11:48    [21958183]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Firebird, InterBase Ответить