您的位置:首页 > 其它

Hibernate in action阅读笔记-吵吵冷饭-事物并发缓存

2013-03-08 10:39 507 查看
理解数据库事物

现在项目动不动都是高并发大容量项目,网站,互联网等等,Hibernate作为框架如何处理事物,并发和缓存。

事物,acid特性

数据库事物,要么提交,要么回滚

jdbc针对单个数据库,jta是对两个或多个数据存储分布式事物。

Hibernate应用代码在管理环境和非管理软件是一样的,Hibernate提供一个抽象层处理,规避了内部实现细节。

Hiberante的事物API

定义事物的边界

Session session = sessions.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction(); 开始
concludeAuction();
tx.commit();//提交,同步Session状态和数据库
} catch (Exception e) {
if (tx != null) {
try {
tx.rollback();//回滚
} catch (HibernateException he) {
//log he and rethrow e
}
}
throw e;
} finally {
try {
session.close();
} catch (HibernateException he) {
throw he;
}
}

上面代码同时适用于管理和非管理环境,JTA,或JDBC

Flushing the Session

hibernate透明化的实现写后操作,不是马上对session状体回写到数据库中,而是归并许多状态变化,到最少的数据库请求提交到数据库.

Flushing时间点:

事物提交,查询之前,手工Session.flush()

Flushing模式,FlushMode.AUTO,FlushMode.COMMIT,FlushMode.NEVER

理解事物隔离级别:

隔离问题:

Lost update,Dirty read,Unrepeatable read,Second lost updates problem,Phantom read

更新丢失,脏读,不重复读,第二次丢失更新,幻想读。

隔离级别:

Read uncommitted,允许脏读,但是不丢失更新,可能是排他写锁

Read committed,允许非重复读,不是脏读,临时共享读锁和排他写锁,读事物不影响其他事物访问数据,但是写事物阻止一切事物

Repeatable read,不允许非重复读,和脏读,共享读锁,和排他锁

Serializable 最严格,事物都要顺序执行。

选择隔离级别:

Read uncommitted会产生bug,影响数据一致性,排除

Serializable 性能受影响

Repeatable read,避免了一个事物更改的数据,被另一个并发事物所更改,但是这并不是唯一的方法,效率不高,而且不能避免幻想读。

Hibernate第一级缓存和版本数据提供了重复读特性。版本保证不能发生第二次丢失更新问题,
一级cache session保证了数据不被其他的并发事物所影响。

不鼓励使用Repeatable read,

那就是剩下了Read committed,呵呵

设置Setting an isolation level

1—Read uncommitted isolation
■ 2—Read committed isolation
■ 4—Repeatable read isolation
■ 8—Serializable isolation

悲观锁

select .... for update

几种锁模式:

■ LockMode.NONE—Don’t go to the database unless the object isn’t in either
cache. 如果有缓存,就不访问数据库
■ LockMode.READ—Bypass both levels of the cache, and perform a version
check to verify that the object in memory is the same version that currently
exists in the database. 绕过双层缓存,并且版本检查去确认内存对象和数据库中版本一致
■ LockMode.UPDGRADE—Bypass both levels of the cache, do a version check
(if applicable), and obtain a database-level pessimistic upgrade lock, if
that is supported.绕过双层缓存,并且版本检查去确认内存对象和数据库中版本一致,并得到悲观锁,
■ LockMode.UPDGRADE_NOWAIT—The same as UPGRADE, but use a SELECT...FOR
UPDATE NOWAIT on Oracle. This disables waiting for concurrent lock releases,
thus throwing a locking exception immediately if the lock can’t be obtained.
不等待当前锁释放,会抛出异常,如果得不到悲观锁
■ LockMode.WRITE—Is obtained automatically when Hibernate has written to
a row in the current transaction (this is an internal mode; you can’t specify
it explicitly).写模式

应用事物

所谓应用事物,从用户角度来看,被认为一个简单的工作单元的商业过程,必须要横跨多个用户客户端得请求。一个粗粒度的广域的应用事物,比如,通过多个界面,多个步骤收集数据,最后完成操作。

既然我们不能用数据库保证当前应用事物隔离和原子性,隔离成为应用事物的关注点。

举例说明:

如果有两个管理员同时打开查看评论界面,并修改,提交了。有三种方法来处理并发试图写数据操作。

1,最后提交胜出,两种写数据库操作都成功,第二次写操作覆盖第一次写操作,无错报出

2.第一次提交胜出,第一次修改持久化后,用户提交第二次操作报错,用户必须重新进行业务过程,来检索更新的评论,再修改,再提交。这就是我们经常说的乐观锁。

3.合并两个提交结果,第一次提交完成,第二次提交也被用户选择性应用。

1的实现方法,是有问题,不允许的,第二种和第三种很类似,可以接受的

Hibernate可以帮助我们实现第二种,和第三种策略,通过控制版本的乐观锁。

Hibernate 的管理版本:

通过时间戳,或者是版本属性,相对时间戳,版本属性更可靠。

Session的粒度:

Session定义了对象身份的范围,Hibernate的事物实例匹配数据库事物范围

session和事物有一对一的情况。通常称为每个请求一个session

一个长运行的应用事物,包括两个客户请求和响应生命圈,加载数据通过第一个session,修改完数据,把脱离数据再重新附到新的session,hibernate会自动的进行版本控制。这种称为带有游离数据的每个请求一个session

另外的一种,长session或者叫一个应用事物一个session,session可以序列化到http session中。一个长session可以有两次数据库连接事物。

其他乐观锁:把要修改的数据字段,以前的数据字段内容作为查找条件,只更新这个修改数据字段。

举例如下:

update COMMENTS set COMMENT_TEXT='New text'
where COMMENT_ID=123
and COMMENT_TEXT='Old Text'
and RATING=5
and ITEM_ID=3
and FROM_USER_ID=45

Caching theory and practice

缓存是位于数据库和应用之间,存在于应用服务器的机器内存和硬盘中,是当前数据库状态代表。

cache策略和范围:

事物范围,确切的数据事物或者应用事物范围。

过程范围,多个事物或工作单元共享数据

集群范围,多个事物或工作单位共享,或一个集群内多台计算机共享

cache和对象身份

事物范围内,对象身份是一致的,比如两次查找同一个id,返回的对象是相同。

过程范围内,对象身份是不一致的

集群范围内,对象身份相同更不能保证。

cache和并发

任何ORM实现都允许多个工作单元共享相同持久对象实例,这样,必须提供一些对象级别的锁,来确保并发存取的同步,这样一来,会导致死锁,hibernate为每一个工作单元维护着一组实例集合,第一级cache能保证事物级别范围内对象身份相同,是最好的策略为高并发多用户系统。

cache和事物隔离

hibernate二级缓存,存储的对象基本上很少改动的,或改动不频繁。

Hibernate缓存框架:

Hibernate二层缓存框架,第一层缓存是session,是不可选,不能关闭,第二层缓存是可插拔的,范围是过程,或是集群.这层缓存状态的cache,不是持久实例,是可选的,可配置到每个类和每个关联类里面。

使用第一层cache,能确保先后取得相同的持久对象的时候,返回的是同一个java实例

重要的事情,它确保了再互相引用对象图情况下,不能发生栈溢出。在数据库交易完后,不会存在一个冲突的相同数据行的对象代表。所有的变化都要写入数据库。在这个工作单元的变化,这个单元的其他部分是可以见的

如果要管理第一层缓存的话,很多数据放在内存,可以用evict(),清除数据和集合从session

管理session,hibernate不是一个理想工具,进行大量的增加,更新工作,会造成内存溢出。session.clear()可以清除所有的对象。

Hibernate二级缓存,确切是sessionfactory 范围。

Persistent instances are stored in the second-level cache in a disassembled form.
Think of disassembly as a process a bit like serialization (the algorithm is much,
much faster than Java serialization, however).类似于序列化

并发内置策略:

并发策略是个中间物件,负责存储和检索从cache中,

四种策略,严格程度依次递减,事物级别,读写,nonstrict-read-write非严格读写,read-only只读

选择合适的cache提供者:

■ EHCache is intended for a simple process scope cache in a single JVM. It can
cache in memory or on disk, and it supports the optional Hibernate query
result cache.
■ OpenSymphony OSCache is a library that supports caching to memory and disk
in a single JVM, with a rich set of expiration policies and query cache support.
■ SwarmCache is a cluster cache based on JGroups. It uses clustered invalidation
but doesn’t support the Hibernate query cache.
■ JBossCache is a fully transactional replicated clustered cache also based on
the JGroups multicast library. The Hibernate query cache is supported,
assuming that clocks are synchronized in the cluster

实践cache

EHCache,

JbossCache两种。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐