За Spring Data 1.6 или по-висока
@Lock
се поддържа от CRUD методи от версия 1.6 на Spring Data JPA (всъщност вече има крайъгълен камък
на разположение). Вижте този тикет
за повече подробности.
С тази версия вие просто декларирате следното:
interface WidgetRepository extends Repository<Widget, Long> {
@Lock(LockModeType.PESSIMISTIC_WRITE)
Widget findOne(Long id);
}
Това ще накара частта за внедряване на CRUD на проксито на резервното хранилище да приложи конфигурирания LockModeType към find(…)
извикване на EntityManager
.
От друга страна,
За предишна версия на Spring Data 1.6
Пролетните данни са песимистични @Lock
анотациите се прилагат само (както посочихте) за заявки. Няма анотации, за които знам, че могат да засегнат цяла транзакция. Можете или да създадете findByOnePessimistic
метод, който извиква findByOne
с песимистично заключване или можете да промените findByOne
винаги да получавате песимистично заключване.
Ако искате да приложите свое собствено решение, вероятно бихте могли. Под капака @Lock
анотацията се обработва от LockModePopulatingMethodIntercceptor
който прави следното:
TransactionSynchronizationManager.bindResource(method, lockMode == null ? NULL : lockMode);
Можете да създадете статичен мениджър за заключване, който има ThreadLocal<LockMode>
членска променлива и след това има аспект, обвит около всеки метод във всяко хранилище, което извика bindResource с режим на заключване, зададен в ThreadLocal. Това ще ви позволи да зададете режима на заключване за всяка нишка. След това можете да създадете свой собствен @MethodLockMode
анотация, която ще обвие метода в аспект, който задава специфичния за нишката режим на заключване преди изпълнението на метода и го изчиства след изпълнението на метода.
Връзка към ресурс:
- Как да активирам LockModeType.PESSIMISTIC_WRITE, когато търсим обекти с Spring Data JPA?
- Как да добавите персонализиран метод към Spring Data JPA
- Време за изчакване на Spring Data Pessimistic Lock с Postgres
- JPA Query API
Различни примери за време на изчакване на песимистично заключване
Задаване на песимистично заключване
Обект на обект може да бъде заключен изрично чрез метода за заключване:
em.lock(employee, LockModeType.PESSIMISTIC_WRITE);
Първият аргумент е обект на обект. Вторият аргумент е исканият режим на заключване.
TransactionRequiredException
се хвърля, ако няма активна транзакция, когато се извиква заключване, тъй като изричното заключване изисква активна транзакция.
LockTimeoutException
се хвърля, ако исканото песимистично заключване не може да бъде предоставено:
PESSIMISTIC_READ
заявката за заключване е неуспешна, ако друг потребител (който е представен от друг екземпляр на EntityManager) в момента притежаваPESSIMISTIC_WRITE
заключване на този обект на база данни.PESSIMISTIC_WRITE
заявката за заключване е неуспешна, ако друг потребител в момента притежава илиPESSIMISTIC_WRITE
заключване илиPESSIMISTIC_READ
заключете този обект на база данни.
Задаване на подсказка за заявка (обхвати)
Подсказките за заявка могат да бъдат зададени в следните обхвати (от глобален до локален):
За цялата единица за постоянство - с помощта на persistence.xml
свойство:
<properties>
<property name="javax.persistence.query.timeout" value="3000"/>
</properties>
За EntityManagerFactory - използване на createEntityManagerFacotory
метод:
Map<String,Object> properties = new HashMap();
properties.put("javax.persistence.query.timeout", 4000);
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("pu", properties);
За EntityManager - използване на createEntityManager
метод:
Map<String,Object> properties = new HashMap();
properties.put("javax.persistence.query.timeout", 5000);
EntityManager em = emf.createEntityManager(properties);
или използвайки метода setProperty:
em.setProperty("javax.persistence.query.timeout", 6000);
За named query
дефиниция - използване на hints
елемент:
@NamedQuery(name="Country.findAll", query="SELECT c FROM Country c",
hints={@QueryHint(name="javax.persistence.query.timeout", value="7000")})
За конкретно изпълнение на заявка - чрез setHint
метод (преди изпълнение на заявка):
query.setHint("javax.persistence.query.timeout", 8000);