У меня есть веб-приложение, в котором пользователи могут изменять данные одновременно. На данный момент я включаю старые значения строк в каждую форму и обновляю строку только в том случае, если данные совпадают. С SQLite это единственный вариант. Это некрасиво, и я рассматриваю возможность перехода на другую базу данных SQL, если это поможет сделать это лучше. Есть ли в PostgreSQL или MySQL неявные временные метки строк или номера версий, которые можно было бы использовать вместо этого?
ProstgreSQL, оптимистичный параллелизм MySQL
Ответы (3)
Лучше использовать числовой счетчик, чем метку времени. Какой бы точной ни была метка времени, возможно, что две версии данных могут быть зафиксированы одновременно и получить одну и ту же метку времени. Используя числовой счетчик (например, update mytable set counter=counter+1, data=? where id=? and counter=?
), каждый раз, когда строка изменяется, она получает уникальное значение счетчика. (Укажите исходное значение счетчика в предложении where, если данные были изменены кем-то другим, никакие строки не будут сопоставлены.)
Хотя это не «неявное» решение, я думаю, что это нормально. В таких библиотеках, как Hibernate, есть средства, позволяющие делать подобные вещи автоматически, поэтому вашему коду не нужно об этом беспокоиться.
MySQL имеет TIMESTAMP
тип данных, который можно использовать для этой цели в сочетании с ограничениями DEFAULT CURRENT_TIMESTAMP
и ON UPDATE CURRENT_TIMESTAMP
.
В PostgreSQL в каждой таблице есть «скрытое поле» с именем xmin
, которое можно использовать для определения версии строки.
xid
, когда транзакция выполняется и обновляет строку, или только когда транзакция была зафиксирована и строка была изменена.
- person ; 31.01.2011
xid
s потенциально может переполниться при изменении данных (очень маловероятно, но это необходимо учитывать), поэтому я не уверен, следует ли на них полагаться.
- person ; 01.02.2011
age()
). Если вы обновите строку, вы увидите новое xmin
в новой версии строки сразу, а не сразу после завершения транзакции.
- person araqnid; 01.02.2011
AFAIK, для получения метки времени обновления в Postgres требуется триггер, см. Этот очень похожий вопрос:
Обновить метку времени при обновлении строки в PostgreSQL
Этот вопрос (и ответ Эрика) указывают на то, что MySQL поддерживает это без триггера.