`

EntityEntry, EntityKey, Cache..Hibernate源码研究碎得(13)

阅读更多


如上篇结束时所言,本篇中着重研究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.

2
1
分享到:
评论

相关推荐

    esql查询分析器(含源码)

    2. **实体命名**:在ESQL中,你可以使用`EntitySet`名称来引用表,`EntityKey`来标识特定记录,以及`NavigationProperty`来导航关联。 3. **函数支持**:ESQL支持多种内置函数,如数学函数(如`COUNT`,`SUM`),...

    用友U9自定义审批流(开发).pdf

    subscriber.EntityKey = this.Entity.Key; EventHelper.SubscribeApprovalResultEvent(this.Entity.Key, subscriber); } return toState; } ``` 3. **审核事件驱动**:当实体经过审核后,根据审核结果更新实体...

    NET4.0类库图098-115952-NETFX4-Poster.pdf

    1. **System.Data**:EntityKey、IExtendedDataRecord的更新,以及DbCommandTree、DbExpression、DbQueryCommandTree和DbExpressionBuilder等类的更新,表明了.NET Framework 4.0在数据访问和查询方面的改进,尤其在...

    ttms最终版.zip

    - `EntityKey.dat`:可能包含了系统中各种实体(如剧目、场次、工作室等)的关键信息,用于快速检索和关联操作。 - `Play.dat`:剧目信息,包括剧名、时长、导演、演员等。 - `Schedule.dat`:演出日程安排,记录...

    .NET Framework 类库参考手册(System.Data 命名空间) [微软官方 MSDN 节选]

    EntityKey EntityKeyMember EntitySqlException EnumerableRowCollection EnumerableRowCollection TRow EnumerableRowCollectionExtensions EvaluateException FillErrorEventArgs ForeignKeyConstraint ...

    microsoft.net.framework.2.0 Microsoft .NET Framework v2.0

    4. ADO.NET改进:2.0版本的ADO.NET增强了数据访问能力,引入了EntitySet和EntityKey,为后来的ADO.NET Entity Framework打下基础。 5. Windows Forms增强:Windows Forms在2.0版本中增加了大量新控件和功能,如...

    用友U9自定义单据(高级).pdf

    - **实体的Key(强类型的EntityKey)**:解释实体Key的概念及其作用,如何使用强类型的EntityKey进行数据操作。 - **实体的查询类Finder**:学习如何利用Finder类进行实体的查找操作,包括Find、FindByID、FindAll等...

    ADO.NET EF中的实体修改方法

    context.ApplyPropertyChanges(region.EntityKey.EntitySetName, region); context.SaveChanges(); } ``` 在这个例子中,我们首先在不跟踪(NoTracking)模式下获取实体,这样它就与任何`DbContext`分离了。然后,...

    C# GroupBy的基本使用教程

    为了解决这个问题,我们需要确保自定义的 `EntityKey` 类重写了 `Equals` 和 `GetHashCode` 方法,以便基于属性值进行相等比较: ```csharp class EntityKey { public int PropertyA { get; set; } public string...

    WCF里使用EF的poco生成数据契约的小例子

    在EF中,POCO类没有继承自EF的EntityObject,也没有包含任何EF特定的属性(如EntityKey)。这使得POCO类可以独立于EF工作,方便在WCF服务中使用。 2. **为什么要在WCF中使用EF的POCO?** 使用POCO作为数据契约可以...

    odata-client:OData客户端库

    $updatedEntity = $client->getEntity('YourEntitySetName', 'entityKey'); $updatedEntity->setPropertyValue('property', 'newValue'); $client->updateEntry($updatedEntity); ``` - 删除: ```php $...

    ZZDownloader

    ZZ下载器用法实现子类继承基类ZZDownloadBaseEntity并实现ZZDownloadParserProtocol 实现子类...operation.key = [entity entityKey ]; [[ZZDownloadTaskManagerV2 shared ] addOp: operation withEntity: entity block

Global site tag (gtag.js) - Google Analytics