ProstgreSQL, оптимистичный параллелизм MySQL

У меня есть веб-приложение, в котором пользователи могут изменять данные одновременно. На данный момент я включаю старые значения строк в каждую форму и обновляю строку только в том случае, если данные совпадают. С SQLite это единственный вариант. Это некрасиво, и я рассматриваю возможность перехода на другую базу данных SQL, если это поможет сделать это лучше. Есть ли в PostgreSQL или MySQL неявные временные метки строк или номера версий, которые можно было бы использовать вместо этого?


person Community    schedule 31.01.2011    source источник


Ответы (3)


Лучше использовать числовой счетчик, чем метку времени. Какой бы точной ни была метка времени, возможно, что две версии данных могут быть зафиксированы одновременно и получить одну и ту же метку времени. Используя числовой счетчик (например, update mytable set counter=counter+1, data=? where id=? and counter=?), каждый раз, когда строка изменяется, она получает уникальное значение счетчика. (Укажите исходное значение счетчика в предложении where, если данные были изменены кем-то другим, никакие строки не будут сопоставлены.)

Хотя это не «неявное» решение, я думаю, что это нормально. В таких библиотеках, как Hibernate, есть средства, позволяющие делать подобные вещи автоматически, поэтому вашему коду не нужно об этом беспокоиться.

person Adrian Smith    schedule 31.01.2011

MySQL имеет TIMESTAMP тип данных, который можно использовать для этой цели в сочетании с ограничениями DEFAULT CURRENT_TIMESTAMP и ON UPDATE CURRENT_TIMESTAMP.

В PostgreSQL в каждой таблице есть «скрытое поле» с именем xmin, которое можно использовать для определения версии строки.

person Eric Petroelje    schedule 31.01.2011
comment
Обновляется ли xid, когда транзакция выполняется и обновляет строку, или только когда транзакция была зафиксирована и строка была изменена. - person ; 31.01.2011
comment
@ott - я считаю, что обновляется только после совершения транзакции. - person Eric Petroelje; 31.01.2011
comment
Также кажется, что xids потенциально может переполниться при изменении данных (очень маловероятно, но это необходимо учитывать), поэтому я не уверен, следует ли на них полагаться. - person ; 01.02.2011
comment
xid, поэтому вы должны знать правила их сравнения (например, с помощью функции age()). Если вы обновите строку, вы увидите новое xmin в новой версии строки сразу, а не сразу после завершения транзакции. - person araqnid; 01.02.2011

AFAIK, для получения метки времени обновления в Postgres требуется триггер, см. Этот очень похожий вопрос:

Обновить метку времени при обновлении строки в PostgreSQL

Этот вопрос (и ответ Эрика) указывают на то, что MySQL поддерживает это без триггера.

person Ken Downs    schedule 31.01.2011
comment
Отметки времени обычно не подходят. Я мог бы сделать это и в SQLite. Управление версиями должно быть задачей базы данных, а не приложения. - person ; 31.01.2011