2013-07-03 2 views
0

"for update"문을 사용하여 mysql 데이터베이스의 일부 행에 대한 잠금을 얻으려고합니다. 이를 위해 나는 Hibernate Transaction의 중간에 Criteria를 만들고 그것에 대한 잠금을 설정한다. 쿼리가 제대로 데이터베이스로 전송됩니다 setLockMode를 사용Hibernate 트랜잭션과 'for update'

crit = session.createCriteria(AppIosVersion.class) 
       .add(Restrictions.eq("version", version)) 
       .setLockMode(LockMode.PESSIMISTIC_WRITE); 

이 내가 mysql.log에서 볼 것입니다 :

 133 Query SET autocommit=0 
      133 Query SET autocommit=1 
      133 Query SET autocommit=0 
      133 Query select this_.Version as Version1_5_0_, this_.EditTimeStamp as EditTime2_5_0_, this_.IsActive as IsActive3_5_0_ from AppAndroidVersion this_ where this_.Version='0.2' for update 
130703 16:46:03 133 Query rollback 
      133 Query SET autocommit=1 

문제는 이 업데이트 문에 허용하지 않는다는 것입니다 최대 절전 모드 beginTransaction()이 START TRANSACTION의 mysql이 아니기 때문에 잠금을 획득합니다.

내 최대 절전 모드 구성은 다음과 같습니다 (저는 Spring을 사용하지 않습니다).

<property name="connection.driver_class">com.mysql.jdbc.Driver</property> 


    <property name="connection.url">jdbc:mysql://localhost:3306/Versions?autoReconnect=true</property> 
    <property name="connection.username">name</property> 
    <property name="connection.password">password</property> 

    <!-- Session properties --> 
    <!-- <property name="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property> --> 
    <property name="hibernate.current_session_context_class">org.hibernate.context.internal.ThreadLocalSessionContext</property> 

    <property name="hibernate.connection.autocommit">false</property> 

    <!-- configuration pool via c3p0--> 
    <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property> 
    <property name="hibernate.c3p0.max_size">100</property> 
    <property name="hibernate.c3p0.min_size">10</property> 
    <property name="hibernate.c3p0.acquire_increment">2</property> 
    <property name="hibernate.c3p0.idle_test_period">180</property> 
    <property name="hibernate.c3p0.max_statements">0</property> 
    <property name="hibernate.c3p0.timeout">600</property> 
    <property name="hibernate.c3p0.debugUnreturnedConnectionStackTraces">true</property> 
    <property name="hibernate.c3p0.unreturnedConnectionTimeout">180</property> 

    <!-- SQL dialect --> 
    <property name="dialect">org.hibernate.dialect.MySQLDialect</property> 
+0

이 게시물에는 거의 같은 질문이 있습니다. http://stackoverflow.com/questions/5019983/hibernate-session-begintransaction-call-and-mysql-start-transaction – ecostanzi

답변

0

Spring과 같은 컨테이너에서 제공하는 선언적 트랜잭션 관리를 사용하지 않으면 트랜잭션을 명시 적으로 처리해야합니다.

하나의 간단한 방법은 스프링과 마찬가지로 TransactionTemplate을 구현하는 것입니다.

그런데 'select xxx for update'와 같은 문구를 사용할 때는 잠금을 제대로 해제해야하며 다른 트랜잭션이 잠긴 행을 만지지 않도록주의하십시오.

관련 문제