2013-04-02 3 views
3

У меня возникла проблема с доступом и обновлением данных на mySQL в Spring Framework, и я хочу спросить всех наиболее эффективный способ блокировки строки TABLE.Как синхронизировать доступ к базе данных весной

Предположим, у меня есть две таблицы: одна запись всех кругов с их идентификаторами и позициями, другая запись всех квадратов с одинаковыми столбцами. положение каждого круга может быть изменено независимо, так же как и квадраты. Но позиции квадратов также можно отрегулировать, перемещая положение кругов. псевдо-код следующим образом:

Public ShapeMovingService{ 

    @Transaction (isolation=required) 
    public moveCirclePosition(int id, int newPosition){ 
     //move circle=id to a new position 
     //also move the square which relates to this circle accordingly 
    } 
    @Transaction (isolation=required) 
    public moveSquarePosition(int id, int newPosition){ 
     //move square=id to a new position 
    } 
} 


public CircleDao extends JdbcTemplateSupport{ 
    public updatePosition(int id, int position){ 
     //query a circle from circle TABLE with id 
     //update the position of the circle 
     //ALSO: modify the position of the square which relates to this circle 
    } 

} 

public SquareDao extends JdbcTemplateSupport{ 
     public updatePosition(int id, int position){ 
      //query a square from squareTABLE with id 
      //update the position of the square    
     } 
} 

Я сделал несколько потоков для выполнения следующих задач:

  • Два потока постоянно обновлять положение окружности ид = 1
  • Один потока продолжает обновлять позиции круга id = 2
  • Один поток продолжает обновлять положение квадрата id = 1
  • Один поток продолжает обновлять положение квадрата id = 2

Перемещение положения круга id = 2 будет влиять на квадрат позиции id = 1; Круг id = 1 не имеет отношения к другим квадратам, и квадрат id = 2.

Мой вопрос: в какой момент я должен заблокировать операцию базы данных либо аннотацией транзакции, либо синхронизированным ключевым словом, чтобы не произошло повреждение данных? Тем не менее различные круги могут обновляться одновременно. Прямо сейчас я блокирую функцию updatePosition, но это означает, что за один раз может быть обновлен только один круг/квадрат.

Благодарим за любые предложения.

ответ

1

Вы можете исследовать поле типа версии hibernate, оно может решить эту задачу, и если вы не используете спящий режим, то можете подумать о том, чтобы реализовать то же самое, что и часть базы dao.

Сообщите, если вам нужны детали.

+0

Не могли бы вы быть более конкретными в поле типа версии? На данный момент я не использую Hibernate. Спасибо –

+0

Хорошо, если мы поговорим о поле типа версии, вы можете иметь столбец timestamp в ваших таблицах, который вы хотите защитить, и убедитесь, что после каждой вставки или обновления в строку поле метки времени обновляется текущим один (тот же запрос). Теперь во время следующего обновления или вставки проверьте это поле, если текущая дата меньше, чем у вас уже есть (означает, что строка уже была обновлена), иначе есть триггер для этой таблицы, которая работает до обновления, отметьте поле timestamp и повышать ошибку, если дата в запросе меньше, чем то, что уже помогло по строке. –

+0

Я вижу логику сейчас, большое спасибо. Так что Hibernate способен выполнять такую ​​проверку самостоятельно без всяких проблем со стороны программиста? –

0

Вам необходимо сделать пессимистичную и оптимистичную блокировку. Крепления для фиксации .see How to prevent concurrency issue in UPDATE via iBatis.

+0

Спасибо. Я попробовал диспетчер транзакций Spring, но он не смог решить эту проблему. –

+0

Какой источник данных вы используете?. Знайте, что не все источники данных поддерживают все уровни изоляции. Вам нужно проконсультироваться с документацией вашего источника данных, уровень изоляции которой доступен. –

+0

Либо вы можете предоставить свою реализацию блокировки с использованием концепции метки времени базы данных. Сопоставьте отметку времени перед любой операцией для каждого потока, запрашивающего операцию БД. –