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

理解数据库事物

现在项目动不动都是高并发大容量项目,网站,互联网等等,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两种。

 

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/guquanyou/archive/2013/03/08/2945944.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值