如上篇结束时所言,本篇中着重研究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. **实体命名**:在ESQL中,你可以使用`EntitySet`名称来引用表,`EntityKey`来标识特定记录,以及`NavigationProperty`来导航关联。 3. **函数支持**:ESQL支持多种内置函数,如数学函数(如`COUNT`,`SUM`),...
subscriber.EntityKey = this.Entity.Key; EventHelper.SubscribeApprovalResultEvent(this.Entity.Key, subscriber); } return toState; } ``` 3. **审核事件驱动**:当实体经过审核后,根据审核结果更新实体...
1. **System.Data**:EntityKey、IExtendedDataRecord的更新,以及DbCommandTree、DbExpression、DbQueryCommandTree和DbExpressionBuilder等类的更新,表明了.NET Framework 4.0在数据访问和查询方面的改进,尤其在...
- `EntityKey.dat`:可能包含了系统中各种实体(如剧目、场次、工作室等)的关键信息,用于快速检索和关联操作。 - `Play.dat`:剧目信息,包括剧名、时长、导演、演员等。 - `Schedule.dat`:演出日程安排,记录...
EntityKey EntityKeyMember EntitySqlException EnumerableRowCollection EnumerableRowCollection TRow EnumerableRowCollectionExtensions EvaluateException FillErrorEventArgs ForeignKeyConstraint ...
4. ADO.NET改进:2.0版本的ADO.NET增强了数据访问能力,引入了EntitySet和EntityKey,为后来的ADO.NET Entity Framework打下基础。 5. Windows Forms增强:Windows Forms在2.0版本中增加了大量新控件和功能,如...
- **实体的Key(强类型的EntityKey)**:解释实体Key的概念及其作用,如何使用强类型的EntityKey进行数据操作。 - **实体的查询类Finder**:学习如何利用Finder类进行实体的查找操作,包括Find、FindByID、FindAll等...
context.ApplyPropertyChanges(region.EntityKey.EntitySetName, region); context.SaveChanges(); } ``` 在这个例子中,我们首先在不跟踪(NoTracking)模式下获取实体,这样它就与任何`DbContext`分离了。然后,...
为了解决这个问题,我们需要确保自定义的 `EntityKey` 类重写了 `Equals` 和 `GetHashCode` 方法,以便基于属性值进行相等比较: ```csharp class EntityKey { public int PropertyA { get; set; } public string...
在EF中,POCO类没有继承自EF的EntityObject,也没有包含任何EF特定的属性(如EntityKey)。这使得POCO类可以独立于EF工作,方便在WCF服务中使用。 2. **为什么要在WCF中使用EF的POCO?** 使用POCO作为数据契约可以...
$updatedEntity = $client->getEntity('YourEntitySetName', 'entityKey'); $updatedEntity->setPropertyValue('property', 'newValue'); $client->updateEntry($updatedEntity); ``` - 删除: ```php $...
ZZ下载器用法实现子类继承基类ZZDownloadBaseEntity并实现ZZDownloadParserProtocol 实现子类...operation.key = [entity entityKey ]; [[ZZDownloadTaskManagerV2 shared ] addOp: operation withEntity: entity block