2010-08-14 3 views
1

У меня есть приложение, в котором в зависимости от типа добавляемой или обновляемой транзакции номер билета может увеличиваться или не увеличиваться. Я не могу использовать тип данных SERIAL для номера билета, потому что он увеличивался бы независимо от типа транзакции, поэтому я определил номер билета как INT. Таким образом, в многопользовательской среде пользователя, если пользователь А при добавлении или обновлении транзакции и пользователь B также делает то же самое, я испытываю для типа Тран и если следующий номер билета требуется, тоSERIAL-like INT column

LET ticket = (SELECT MAX(ticket) [WITH ADDLOCK or UPDLOCK?] FROM transactions) + 1 

Однако это должно выполняться точно, когда строка будет совершена или начнутся неприятности. Можете ли вы подумать об этом лучше: Informix, Oracle, MySQL, SQL-Server, 4Js/Genero или другие РСУБД? Это один из основных факторов, который определит, какие RDBMS я собираюсь переписать в свое приложение.

ответ

2

С Informix СУБД, СЕРИЙНЫЙ столбец не изменится после того, как он вставлен; действительно, вы не можете обновить значение SERIAL. Вы можете вставить новое значение с 0 в качестве значения - в этом случае создается новое значение - или вы можете вставить другое значение. Если другое значение уже существует и существует уникальное ограничение, это не сработает; если он не существует, или если нет уникального ограничения для последовательного столбца, то он будет успешным. Если вставленное значение больше самого большого значения, которое было вставлено ранее, то следующий номер, который будет вставлен, будет снова больше. Если введенное число меньше или отрицательно, то на следующий номер не влияет.

Итак, вы можете сделать свое обновление без изменения значения - без проблем. Если вам нужно изменить номер, вам нужно будет удалить и вставить (или вставить и удалить), где вставка имеет нуль. Если вы предпочитаете согласованность и используете транзакции, вы всегда можете удалить, а затем (повторно) вставить строку с тем же номером или с нулем для запуска нового номера. Предположим, у вас есть язык программирования, на котором запущен SQL; Я не думаю, что вы можете настроить ISQL и выполнить это автоматически.

Итак, на данный момент я не вижу проблемы с Informix.

С соответствующей версией IDS (все, что поддерживается) вы можете использовать SEQUENCE для управления введенными значениями. Это основано на синтаксисе и концепции Oracle; DB2 также поддерживает это. Другие СУБД имеют другие эквивалентные (но разные) механизмы для обработки автоматически сгенерированных чисел.

+1

PostgreSQL имеет последовательности, а с 7.x также имеет «SERIAL», который действует как auto_increment MySQL или IDENTITY SQL Server ... –

1

Из ваших тегов трудно определить, какую базу данных вы используете.

Для SQL Server (так как она указана) Я предлагаю

ticket_num = (SELECT MAX(ticket_number) FROM transactions with (updlock)) + 1 
1

Вот что последовательности были созданы и которые поддерживаются большинством баз данных (MySQL является единственным, который не имеет последовательности - не 100% уверен, Informix, хотя)

Любой алгоритм, который опирается на SELECT MAX (id) Анти-шаблон либо мертв-медленен в многопользовательской среде, либо просто не работает корректно в многопользовательской среде.

Если вам также нужна поддержка MySQL, я бы рекомендовал использовать «родной» тип автоматического увеличения в каждой базе данных (серийный номер для PostgreSQL, auto_increment для MySQL, идентификатор для SQL Server, последовательность + триггер в Oracle и т. д.), и пусть драйвер возвращает сгенерированное значение идентификатора

В JDBC существует метод getGeneratedKeys(), и я уверен, что другие интерфейсы имеют что-то подобное.

Смежные вопросы