目前,Hibernate对PostgreSQL的for update nowait语法是不支持的,(Hibernate3.2.4),由于项目的需要,只好自己来实现。Hibernate在解析SQL文的时候,利用的是Hibernate的Dialect,我们可以通过重载org.hibernate.dialect.PostgreSQLDialect来实现对for update nowait的支持。
1.重载PostgreSQLDialect
只需要重写getForUpdateNowaitString()即可
2.修正Hibernate设定文件(hibernate.cfg.xml)
<
hibernate-configuration
>
<
session-factory
>
<
property
name
="connection.driver_class"
>
org.postgresql.Driver
</
property
>
<
property
name
="connection.url"
>
jdbc:postgresql:/localhost/sample
</
property
>
<
property
name
="connection.username"
>
guest
</
property
>
<
property
name
="connection.password"
>
guest
</
property
>
<
property
name
="show_sql"
>
true
</
property
>
<
property
name
="dialect"
>
test.MyPostgreSQLDialect
</
property
>
← 修正这里
<
mapping
resource
="test/Test.hbm.xml"
/>
</
session-factory
>
</
hibernate-configuration
>
3.如果利用Spring去连接Hibernate,则在Sping的applicationContext.xml文件中要做以下修正
<
bean
id
="sessionFactory"
class
="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
>
<
property
name
="dataSource"
>
<
ref
local
="dataSource"
/>
</
property
>
<
property
name
="configLocation"
>
<
value
>
WEB-INF/classes/koichi/hibernate.cfg.xml
</
value
>
</
property
>
<
property
name
="configurationClass"
>
<
value
>
org.hibernate.cfg.AnnotationConfiguration
</
value
>
</
property
>
<
property
name
="hibernateProperties"
>
<
props
>
<
prop
key
="hibernate.show_sql"
>
true
</
prop
>
<
prop
key
="hibernate.dialect"
>
test.MyPostgreSQLDialect
</
prop
>
← 这里需要修改
</
props
>
</
property
>
</
bean
>
3.nowait的代码实现
只需要指定LockMode.UPGRADE_NOWAIT即可。
HogeDTO dto
=
(HogeDTO) getHibernateTemplate().
load(HogeDTO. class , hogeid, LockMode.UPGRADE_NOWAIT);
发生Lock错误的时候,会报出以下消息:
Caused by: org.postgresql.util.PSQLException: ERROR: could not obtain lock on row in relation " hoge "
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java: 1512 )
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java: 1297 )
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java: 188 )
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java: 437 )
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java: 353 )
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java: 257 )
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java: 92 )
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java: 137 )
at org.hibernate.loader.Loader.getResultSet(Loader.java: 1676 )
at org.hibernate.loader.Loader.doQuery(Loader.java: 662 )
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java: 223 )
at org.hibernate.loader.Loader.loadEntity(Loader.java: 1782 )
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java: 93 )
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java: 81 )
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java: 2729 )
at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java: 365 )
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java: 346 )
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java: 123 )
at org.hibernate.event.def.DefaultLoadEventListener.lockAndLoad(DefaultLoadEventListener.java: 272 )
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java: 90 )
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java: 809 )
at org.hibernate.impl.SessionImpl.load(SessionImpl.java: 792 )
at org.hibernate.impl.SessionImpl.load(SessionImpl.java: 787 )
at org.springframework.orm.hibernate3.HibernateTemplate$ 3 .doInHibernate(HibernateTemplate.java: 478 )
at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java: 358 )
... 77 more
1.重载PostgreSQLDialect
只需要重写getForUpdateNowaitString()即可
import
org.hibernate.dialect.PostgreSQLDialect;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
class
MyPostgreSQLDialect
extends
PostgreSQLDialect
{
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
@Override
public String getForUpdateNowaitString() {
return " for update nowait";
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
2.修正Hibernate设定文件(hibernate.cfg.xml)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
3.如果利用Spring去连接Hibernate,则在Sping的applicationContext.xml文件中要做以下修正
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
3.nowait的代码实现
只需要指定LockMode.UPGRADE_NOWAIT即可。
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
load(HogeDTO. class , hogeid, LockMode.UPGRADE_NOWAIT);
发生Lock错误的时候,会报出以下消息:
Caused by: org.postgresql.util.PSQLException: ERROR: could not obtain lock on row in relation " hoge "
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java: 1512 )
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java: 1297 )
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java: 188 )
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java: 437 )
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java: 353 )
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java: 257 )
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java: 92 )
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java: 137 )
at org.hibernate.loader.Loader.getResultSet(Loader.java: 1676 )
at org.hibernate.loader.Loader.doQuery(Loader.java: 662 )
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java: 223 )
at org.hibernate.loader.Loader.loadEntity(Loader.java: 1782 )
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java: 93 )
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java: 81 )
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java: 2729 )
at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java: 365 )
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java: 346 )
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java: 123 )
at org.hibernate.event.def.DefaultLoadEventListener.lockAndLoad(DefaultLoadEventListener.java: 272 )
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java: 90 )
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java: 809 )
at org.hibernate.impl.SessionImpl.load(SessionImpl.java: 792 )
at org.hibernate.impl.SessionImpl.load(SessionImpl.java: 787 )
at org.springframework.orm.hibernate3.HibernateTemplate$ 3 .doInHibernate(HibernateTemplate.java: 478 )
at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java: 358 )
... 77 more