Spring-транзакции и их взаимодействие с синхронизированным ключевым словом - PullRequest
0 голосов
/ 22 февраля 2012

У меня есть класс DAO, который использует Spring JDBC для доступа к базе данных SQLite. Я объявил транзакции для самих методов DAO, поскольку мой уровень обслуживания никогда не объединяет запросы в транзакции.

Поскольку я использую несколько рабочих потоков параллельно, но только один поток может обновлять БД SQLite одновременно, я использую synchronized для сериализации доступа к DAO.

Сначала я синхронизировался извне со своим классом обслуживания, например:

synchronized (dao) {
    dao.update(...);
}

Затем я решил, что мог бы также избавиться от внешней синхронизации и поместить synchronized в сам метод DAO:

public synchronized void update(...) {
    // Spring JDBC calls here
}

Странная вещь: мои запросы теперь занимают вдвое больше времени, чем раньше!

Почему?

Ответы [ 2 ]

1 голос
/ 22 февраля 2012

Ну, одно различие очевидно:

synchronized (dao) {
    // here you are synchronizing on the transactional proxy
}

public synchronized void update(...) {
    // and here you are synchronizing on the target class, *inside* the proxy
}

Каковы последствия этого, зависит от вашего другого кода, но это очевидная разница.

0 голосов
/ 22 февраля 2012

Я предполагаю, что ваш метод обновления или весь класс аннотирован с помощью Transactional или обернут транзакционным прокси другим способом. Это означает, что всякий раз, когда вы вызываете метод dao, транзакционный прокси-сервер получает соединение из базы данных из пула, открывает транзакцию и затем вызывает реальный метод.

В вашем первом сценарии вы выполняете синхронизацию, даже не достигнув прокси-сервера, поэтому не происходит никакой магии соединения и транзакции. Во втором сценарии вы делаете ожидающий вызов после этого.

Если есть несколько потоков, пытающихся выполнить одновременные обновления, будет только один, выполняющий обновление, а остальные будут сначала открывать новые подключения, а затем ожидать даосского доступа. Как следствие, вместо постоянного повторного использования одного соединения вы будете использовать несколько соединений. Я могу только догадываться, как это действительно влияет на производительность, но вы можете поэкспериментировать с другим размером пула, начиная с одного.

...