我正在尝试使用“for update”语句获取mysql数据库中某些行的锁定。为此,我在Hibernate Transaction的中间创建一个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
问题是 for update 语句不允许获取锁,因为hibernate beginTransaction()在mysql中不会成为 START TRANSACTION 。
我的hibernate配置如下(我不使用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 :(得分:0)
如果您不使用像Spring这样的容器提供的声明式事务管理,则必须明确处理该事务。
一种简单的方法是像Spring一样实现TransactionTemplate。
顺便说一句,小心使用“select xxx for update”这样的语句,确保正确释放锁定,其他任何事务都不会触及锁定的行。