Hibernate does not lock objects in memory. Your application can expect the behavior as defined by the isolation level of your database transactions.

Note that thanks to the Session, which is also a transaction-scoped cache, Hibernate provides repeatable reads for lookup by identifier and entity queries (not reporting queries that return scalar values).

Hibernate 没有提供在内存中对对象加锁的功能,因此应用的事务隔离级别是完全由数据库来提供的。

借助于session,Hibernate 提供了可重复读的事务隔离级别,但是前提是只有使用identifier and entity queries的可以,使用标量查询则不可以,其原因是hibernate的cache的对象需要是能够被唯一识别的实体对象,标量查询返回的结果是数组,不满足该要求,无法在session级别进行事务的cache

在事务和并发性方面,hibernate不仅提供了基于版本的控制的自动乐观锁机制,同时还提供了API来实现悲观锁机制(通过SELECT FOR UPDATE 语法)

A SessionFactory is an expensive-to-create, threadsafe object intended to be shared by all application threads. It is created once, usually on application startup, from a Configuration instance.

A Session is an inexpensive, non-threadsafe object that should be used once, for a single request, a conversation, single unit of work, and then discarded. A Session will not obtain a JDBC Connection (or a Datasource) unless it is needed, hence consume no resources until used.

Database transactions are never optional, all communication with a database has to occur inside a transaction, no matter if you read or write data.

事务并不是可有可无的,所有的数据库操作都是在事务环境下发生的,不管是read 操作还是write操作。这点一定要名明确,以前曾经误解。

As explained, auto-commit behavior for reading data should be avoided, as many small transactions are unlikely to perform better than one clearly defined unit of work. The latter is also much more maintainable and extensible.

最好关闭自动提交功能,因为使用大量的短数据库事务在性能上未必比一个清晰定义的unit work强,后者更加易于维护和扩展。(以前曾经误解)

 

乐观锁的处理方式

Hibernate checks instance versions at flush time, throwing an exception if concurrent modification is detected.It's up to the developer to catch and handle this exception (common options are the opportunity for the user to merge changes or to restart the business conversation with non-stale data).

在flush的时候检查version,如果发现更改会抛出异常,开发人员可以捕捉该异常,并决定如何处理(要么合并修改,要么放弃修改)

悲观锁的处理方式

悲观锁基本上是靠数据库本身提供的机制来实现,通常只要为jdbc connection指定事务隔离的级别即可。The LockMode class defines the different lock levels that may be acquired by Hibernate.

悲观锁会在读取数据之前获取,因此能够保证当前事务的数据就是最新数据。

 

hibernate的查询分类:

1、标量查询(Scalar queries):返回的记录数组的集合

标量是与数组相对的概念,是一种由单一的值来表征的量。所谓标量查询,就是直接使用原生sql语句的查询,也即返回的是裸数据(只不过hibernate使用ResultSetMetaData将resultset中的每一条记录放到一个数组Object[]中)。

比如

List list = session.createSQLQuery("select * from t_area_person").list();

for (Object object : list) {
            Object[] ob = (Object[]) object;
            for (int i = 0; i < ob.length; i++)
                System.out.print("  " +ob[i]);
            System.out.println();
        }

 

2、实体查询(Entity queries):返回的是实体对象的集合

3、Load方法:lookup by identifier ,返回的是该identifier 对应的对象