За 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);