자바 프로그래머 는 어 리 석 은 새 부터 초보 까지 (76) 히 버 네 이 트 (18) 비관 적 자물쇠 와 낙관적 자물쇠 해결 hibenate 병행
8615 단어 Hibernate
select * from account wherename=”Erica” forupdate
이것
sql
문구 가 잠 겼 다
account
표 의 모든 검색 조건 에 부합 (
name=
”
Erica
”
) 의 기록.이번 트 랜 잭 션 을 제출 하기 전에 (트 랜 잭 션 을 제출 할 때 트 랜 잭 션 과정 에서 잠 금 을 풀 어 줍 니 다) 외부 에서 이 기록 을 수정 할 수 없습니다.
Hibernate
비관 적 인 자물쇠 도 데이터 베 이 스 를 바탕 으로 하 는 자물쇠 체제 로 이 루어 진다.
아래 코드 는 조회 기록 에 대한 잠 금 을 실현 합 니 다.
String hqlStr ="from TUser as user where user.name=‘Erica‘";
Query query = session.createQuery(hqlStr);
query.setLockMode("user",LockMode.UPGRADE); //
List userList = query.list();// ,
query.setLockMode
검색 어 에서 특정 별명 에 대응 하 는 기록 에 잠 금 을 추가 합 니 다.
TUser
클래스 가 별명 을 지 정 했 습 니 다.
“
user
”
), 여기 가 바로 돌아 오 는 모든 것 이다.
user
기록 에 자 물 쇠 를 채우다.
운행 기 를 관찰 하 다
Hibernate
생 성
SQL
문장:
select tuser0_.id as id, tuser0_.name as name,tuser0_.group_id
as group_id, tuser0_.user_type as user_type, tuser0_.sex as sex
from t_user tuser0_ where (tuser0_.name=‘Erica‘ )for update
여기, 이곳
Hibernate
데이터 베 이 스 를 사용 한
for update
자 구 는 비관 적 인 자물쇠 체 제 를 실현 하 였 다.
Hibernate 의 잠 금 모드 는 LockMode. NONE: 잠 금 장치 가 없습니다.LockMode. WRITE: Hibernate 는 Insert 와 Update 기록 에서 자동 으로 가 져 옵 니 다.LockMode. READ: Hibernate 는 기록 을 읽 을 때 자동 으로 가 져 옵 니 다.
상기 세 가지 잠 금 체 제 는 일반적으로 Hibernate 내부 에서 사용 합 니 다. 예 를 들 어 Hibernate 는 Update 과정 에서 대상 이 외부 에서 수정 되 지 않도록 save 방법 실현 에서 자동 으로 목표 대상 에 WRITE 잠 금 을 추가 합 니 다.LockMode. UPGRADE: 데이터베이스 의 for update 자 구 를 이용 하여 자 물 쇠 를 추가 합 니 다.LockMode. UPGRADE_NOWAIT: Oracle 의 특정한 실현, Oracle 의 for update nowait 자 구 를 이용 하여 잠 금 을 실현 합 니 다.위의 두 가지 잠 금 체 제 는 우리 가 응용 층 에서 비교적 자주 사용 하 는 것 이다. 잠 금 을 추가 하 는 것 은 보통 다음 과 같은 방법 으로 이 루어 진다. Criteria. setLockMode Query. setLockMode Session. lock
검색 이 시작 되 기 전에 (즉, Hiberate 가 SQL 을 생 성하 기 전에) 잠 금 을 설정 해 야 데이터베이스 잠 금 메커니즘 을 통 해 잠 금 처 리 를 할 수 있 습 니 다. 그렇지 않 으 면 데 이 터 는 for update 자 구 를 포함 하지 않 은 Select SQL 을 통 해 불 러 옵 니 다. 데이터베이스 잠 금 이라는 것 은 말 할 수 없습니다.
Hibernate 에서 비관 적 인 자 물 쇠 를 사용 하 는 것 은 매우 쉽 지만 실제 응용 에서 비관 적 인 자 물 쇠 는 거의 사용 되 지 않 는 다. 왜냐하면 이것 은 동시성 을 크게 제한 하고 데이터베이스 밑바닥 을 이용 하여 자 물 쇠 를 유지 하기 때문에 응용 프로그램의 효율 을 크게 떨 어 뜨 린 다.
다음은 hibenateAPI 에서 제공 하 는 get 방법 두 가 지 를 살 펴 보 겠 습 니 다.
Get(Classclazz,Serializable id,LockMode lockMode)
Get(Classclazz,Serializable id,LockOptionslockOptions )
get 방법의 세 번 째 인자 인 'lockMode' 나 'lockOptions' 를 볼 수 있 습 니 다. Hibernate 3.6 이상 버 전에 서' LockMode '는 사용 을 권장 하지 않 습 니 다.방법의 세 번 째 매개 변 수 는 비관 적 인 자 물 쇠 를 설정 하 는 데 사 용 됩 니 다. 세 번 째 매개 변 수 를 사용 한 후에 저희 가 보 내 는 SQL 문 구 는 'for update' 를 추가 하여 데이터 베 이 스 를 잠 그 는 데 사 용 됩 니 다.LockMode 매개 변 수 는 UPGRADE 옵션 을 선택 하면 비관 적 인 자물쇠 가 열 립 니 다.
낙관적 잠 금 (최 적 잠 금)
비관 적 인 자물쇠 에 비해 낙관적 인 자물쇠 체 제 는 더욱 느슨 한 잠 금 체 제 를 채택 했다.비관 적 인 잠 금 은 대부분 상황 에서 데이터 뱅 크 의 잠 금 체제 에 의 해 이 루어 져 작업 의 최대 독점 성 을 확보한다.그러나 이에 따 른 것 은 데이터베이스 성능 의 대량 지출 이다. 특히 긴 사무 에 있어 이런 지출 은 감당 할 수 없다.낙관적 인 자물쇠 메커니즘 이 어느 정도 에 이 문 제 를 해결 했다.낙관적 인 잠 금 은 대부분 데이터 버 전 (Version) 기록 체 제 를 바탕 으로 이 루어 진다.데이터 버 전 이란 무엇 입 니까?즉, 데이터 에 버 전 표 지 를 추가 하 는 것 이다. 데이터 베 이 스 를 바탕 으로 하 는 버 전 솔 루 션 에서 보통 데이터 베 이 스 를 위 한 'version' 필드 를 추가 하여 이 루어 진다.낙관적 잠 금 의 작업 원리: 데 이 터 를 읽 을 때 이 버 전 번 호 를 함께 읽 고 업데이트 할 때 이 버 전 번 호 를 1 로 추가 합 니 다.이때 제출 한 데이터 의 버 전 데 이 터 를 데이터베이스 테이블 에 대응 하 는 기 록 된 현재 버 전 정보 와 비교 하고 제출 한 데이터 버 전 번호 가 데이터베이스 테이블 의 현재 버 전 번호 보다 크 면 업데이트 한다. 그렇지 않 으 면 만 료 된 데이터 라 고 생각한다.
Hibernate 는 낙관적 인 자물쇠 에 3 가지 실현 을 제공 합 니 다.
1. version 기반
2. timestamp 기반
3. 남 겨 진 항목 에 낙관적 인 자 물 쇠 를 추가 합 니 다.
version 기반 낙관적 잠 금 설정:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<classname="com.bzu.hibernate.pojos.People"table="people">
<idname="id"type="string">
<columnname="id"></column>
<generatorclass="uuid"></generator>
</id>
<!--version -->
<versionname="version"column="version"type="integer"></version>
<propertyname="name"column="name"type="string"></property>
</class>
</hibernate-mapping>
주: 실체 클래스 에 속성 version 추가 하 는 것 을 잊 지 마 세 요.
timestamp 기반 낙관적 잠 금 설정:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<classname="com.suxiaolei.hibernate.pojos.People"table="people">
<id name="id"type="string">
<column name="id"></column>
<generator class="uuid"></generator>
</id>
<!--timestamp -->
<timestamp name="updateDate"column="updateDate"></timestamp>
<propertyname="name"column="name"type="string"></property>
</class>
</hibernate-mapping>
다음은 여러 개의 session 을 모 의 하여 version 기반 으로 테스트 를 진행 하 겠 습 니 다.
/*
* session student
*/
Sessionsession1=sessionFactory.openSession();
Session session2=sessionFactory.openSession();
Studentstu1=(Student)session1.createQuery("from Student s wheres.name='tom11'").uniqueResult();
Studentstu2=(Student)session2.createQuery("from Student s wheres.name='tom11'").uniqueResult();
// ,
System.out.println("v1="+stu1.getVersion()+"--v2="+stu2.getVersion());
Transactiontx1=session1.beginTransaction();
stu1.setName("session1");
tx1.commit();
// , ,
System.out.println("v1="+stu1.getVersion()+"--v2="+stu2.getVersion());
Transactiontx2=session2.beginTransaction();
stu2.setName("session2");
tx2.commit();
실행 결과:
Hibernate: insert into studentVersion (ver, name,id) values (?, ?, ?) Hibernate: select student0_.id as id0_, student0_.ver as ver0_, student0_.nameas name0_ from studentVersion student0_ where student0_.name='tom11' Hibernate: select student0_.id as id0_, student0_.ver as ver0_, student0_.nameas name0_ from studentVersion student0_ where student0_.name='tom11' v1=0--v2=0 Hibernate: update studentVersion set ver=?, name=? where id=? and ver=? v1=1--v2=0 Hibernate: update studentVersion set ver=?, name=? where id=? and ver=?Exception in thread "main" org.hibernate.StaleObjectStateException:Row was updated or deleted by another transaction (or unsaved-value mapping wasincorrect): [Version.Student#4028818316cd6b460116cd6b50830001]
두 번 째 '사용자' session 2 가 데 이 터 를 수정 할 때 기 록 된 버 전 번 호 는 session 1 에 의 해 업데이트 되 었 기 때문에 빨간색 이상 을 던 졌 습 니 다. 우 리 는 실제 응용 에서 이 이상 을 처리 할 수 있 습 니 다. 예 를 들 어 처리 과정 에서 데이터 베 이 스 를 다시 읽 는 동시에 현재 의 데이터 와 데이터 베 이 스 를 보 여 줌 으로 써 사용자 가 비교 할 수 있 도록 합 니 다.또는 디자인 프로그램 이 새로운 데 이 터 를 자동 으로 읽 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[JPA] 단방향 연관관계테이블과 컬럼은 결국 엔티티와 필드와 그대로 매핑하기 때문에 매핑방법만 알고 있다면 어렵지 않지만, DB와 JPA는 테이블간의 관계를 표현하는 패러다임에서 큰 차이가 있기 때문에 나 역시 JPA를 처음 접하고 이 부...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.