0

「for update」ステートメントを使用して、mysql データベースのいくつかの行のロックを取得しようとしています。そのために、Hibernate トランザクションの途中で Criteria を作成し、それにロックを設定します。

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

setLockMode を使用すると、クエリはデータベースに正しく送信されます。これは、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

問題は、mysql でhibernate beginTransaction() がSTART TRANSACTIONにならないため、 for updateステートメントがロックを取得できないことです。

私の休止状態の設定は次のとおりです(私は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> 
4

1 に答える 1

0

Spring のようなコンテナーによって提供される宣言型トランザクション管理を使用しない場合は、トランザクションを明示的に処理する必要があります。

簡単な方法の 1 つは、 Spring のようにTransactionTemplateを実装することです。

ところで、'select xxx for update' のようなステートメントを使用する場合は注意してください。ロックを適切に解放し、他のトランザクションがロックされた行に触れないようにしてください。

于 2013-08-21T08:07:28.047 に答える