Hibernate源码研究碎得(十三)

如上篇结束时所言,本篇中着重研究upgradeLock这个方法.



进入方法后第一句就是这个requestedLockMode.greaterThan( entry.getLockMode())判断,若不成立,就马上退出此方法.



有些疑问的是EntityEntry类型的entry里getLockMode有什么意义?再往下追就是EntityEntry里的lockMode是什么时候什么情景下赋值的?


.......................


刚才用Eclipse里实际debug了一番,现在明白了些.


1,那个LockMode所Lock的是缓存里的Entity,把数据从DB中取出并封装成Java中的对象后,先通过addEntity的方式以entityKey为Key,以实际的Entity为value放入到PersistenceContext中的Map类型的entitiesByKey里,(这也就是SessionLevel的Cache吧?),接下来通过下面的参数:


EntityEntry e = new EntityEntry(
status,
loadedState,
rowId,
id,
version,
lockMode,
existsInDatabase,
persister,
session.getEntityMode(),
disableVersionIncrement,
lazyPropertiesAreUnfetched
);


组建一个EntityEntry对象,再利用如下语句entityEntries.put(entity, e)把这个新建的EntityEntry作为value同时那个DB数据的包装产物entity作为Key也放入到PersistenceContext里类型为Map的entityEntries对象中.这样就完成了数据从DB到PersistenceContext里迁移,而且在PersistenceContext里已有了Hibernate意义上的LockMode.



2,这样当开一个Session并利用此Session来get某一个Java对象时,就会先从PersistenceContext里Map来取,若PersistenceContext里有,就取出.这时就要比较当前Session里取Java对象时的LockMode与PersistenceContext里对应EntityEntry里已有的LockMode,若前者大于后者就要来一次upgradeLock,毕竟当把这个Java对象从PersistenceContext里传给业务层后就要保证这个Java对象拥有一个高级别的排它锁,以防止别的Session偷偷地给改掉.这就是方法upgradeLock产生的背景,也正因为此upgradeLock方法也只出现在loadFromSessionCache里. -->不错,把upgradeLock这个方法放在PersistenceContext里来理解一下就通了.

有了上面的分析,对upgradeLock方法的理解就完成一半了.再往下走,就是看这个目标怎么实现了.

就我现在的理解来看,在实现上这个upgradeLock有三个层面的操作:


1,二级缓存层面:通过生成一个包含当前Session及相关重要属性的CacheKey来锁定,也就是注明在二级缓存中想的那个Java对象已有CacheKey占有了,其它的"哥们儿"就别再花心思想这事了.


2,PersistenceContext层面:有判断是否isVersioned,从而来保证Version的一致;在PersistenceContext层面来更新LockMode的级别.


3,DB层面的事务隔离级别:
persister.lock( entry.getId(), entry.getVersion(), object, requestedLockMode, source );
下面又有:
PreparedStatement st = session.getBatcher().prepareSelectStatement( sql );
于是我就连蒙带猜地认为在DB层面上触及到事务的隔离级别了.



到结尾处有一个问题:
if ( persister.hasCache() ) {
persister.getCache().release(ck, lock );
}



怎么finally里的代码块把前面刚刚Lock的给CacheKey的Entity给放了呢?这又不是session里的Trasaction已经结束了.想不明白,这个以后再慢慢体会吧.



不过看了对finally做的如下注释,
"the database now holds a lock + the object is flushed from the cache,so release the soft lock"
虽说没有明白这个finally的作用,但似乎有些验证了前面关于"DB层面的事务隔离级别"的猜想.


这个方法终于搞完了.

作为补充,说一下,Hibernate在commit Trasaction时会把EntityEntry里的LockMode重置成最低级别的LockMode.NONE.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值