Activiti缓存机制解析

Activiti的持久化和缓存最终都是有DbSqlSession处理的,在此主要也是讲这个对象。类图如下。

public class DbSqlSession implements PersistenOperation, Session {

Java代码   收藏代码
  1.     protected SqlSession sqlSession;  
  2.     protected List<PersistentObject> insertedObjects = new ArrayList<PersistentObject>();  
  3.     protected Map<Class<?>, Map<String, CachedObject>> cachedObjects = new HashMap<Class<?>, Map<String, CachedObject>>();  
  4.     protected List<DeleteOperation> deletedObjects = new ArrayList<DeleteOperation>();  
  5. }  

 首先是insert,这里它使用了一个List对插入对象进行缓存,在通过flush()方法,flush之后最终会使用sqlSession把数据鎚入数据源,sqlSesion是所有对象最终持久化的唯一入口。

delete的作法基本上和inert一样,deltet做多了一层封装DeleteOperation,使用这个对象,适配id进行删除。

 

重点是update,这里update要结合select一起使用。在DbSqlSession对象中,没有update方法,update要求先进行select查询对象,更新查询对象,最终flush()的适合,chched容器会检查最终状态是否和查询时的状态一致,如果不一致,才会进行持久化更新。也就是说,用户只需要查询出对象,使用对象的set方法,更新属性,这样子就会默认进行更新了。在实现的适合注意getPersistentState()的实现,也就是说,会使用到属性更新的属性,需要够着一个判断状态更新的对象让cache容器对比。

flush()的时候,cache容器会先清理掉insert对象和delete对象。

我们看看CachedObject对象的设计。

 

Java代码   收藏代码
  1. public static class CachedObject {  
  2.         protected PersistentObject persistentObject;  
  3.         protected Object persistentObjectState;  
  4.   
  5.         public CachedObject(PersistentObject persistentObject, boolean storeState) {  
  6.             this.persistentObject = persistentObject;  
  7.             if (storeState) {  
  8.                 this.persistentObjectState = persistentObject.getPersistentState();  
  9.             }  
  10.         }  
  11.   
  12.         public PersistentObject getPersistentObject() {  
  13.             return persistentObject;  
  14.         }  
  15.   
  16.         public Object getPersistentObjectState() {  
  17.             return persistentObjectState;  
  18.         }  
  19.     }  

 

 这里可以看明白我们属性设置对比和最终持久。当查询的适合,用storeState = true 构造CachedObject, PersistentState会被保存在对象中。外部API通过select对象的引用更新属性,flush()的适合,会拿最终对象的PersistentState与select出来的对象进行对比,如果不一致,就update数据源记录。代码如下。

 

Java代码   收藏代码
  1. public List<PersistentObject> getUpdatedObjects() {  
  2.        List<PersistentObject> updatedObjects = new ArrayList<PersistentObject>();  
  3.        for (Class<?> clazz : cachedObjects.keySet()) {  
  4.            Map<String, CachedObject> classCache = cachedObjects.get(clazz);  
  5.            for (CachedObject cachedObject : classCache.values()) {  
  6.                PersistentObject persistentObject = cachedObject.getPersistentObject();  
  7.                if (!deletedObjects.contains(persistentObject)) {  
  8.                    Object originalState = cachedObject.getPersistentObjectState();  
  9.                    if (!originalState.equals(persistentObject.getPersistentState())) {  
  10.                        updatedObjects.add(persistentObject);  
  11.                    } else {  
  12.                        log.finest("loaded object '" + persistentObject + "' was not updated");  
  13.                    }  
  14.                }  
  15.            }  
  16.        }  
  17.        return updatedObjects;  
  18.    }  

 

 

到这里,我遇到了一个问题,如果我不使用对象属性更新,也想update数据源记录,显然activiti这一套实现机制是不支持的,那怎么办呢?我的解决办法如下。

 

Java代码   收藏代码
  1. /** 
  2.      * 更新数据,对源码的扩展。 
  3.      * 一般的更新是直接通过Entity对象属性设置。此处暴露出一种直接更新对象的方法。 
  4.      *  
  5.      * @param persistentObject 
  6.      */  
  7.     public void update(PersistentObject persistentObject) {  
  8.         PersistentObject oldPersistentObject = selectById(persistentObject.getClass(), persistentObject.getId());  
  9.           
  10.         //先put对象进缓存容器,再讲持久状态回滚,这样flush的时候,会检查到对象状态变化,进而更新对象。  
  11.         CachedObject cachedObject = cachePut(persistentObject, false);  
  12.         cachedObject.persistentObjectState = oldPersistentObject.getPersistentState();  
  13.     }  

 先用select,保证数据源中的记录已经缓存在cache容器中,跟着强制更新PersistentState。保证flush()的时候可以检查状态的一致性。

 

 

activiti依赖Mybatis,关于缓存机制,Mybatis还有自身的机制,有自己的一套缓存回收机制。activiti默认是不适用Mybatis的缓存的,activiti自身的缓存机制够简单,如果在自身command机制里面适用,性能很高,如果是比较复杂的业务场景,会在结合外部扩展适用的话,很可能就不够用了。所有个人认为可以考虑结合Mybatis的缓存机制,混合适用。

猜你喜欢

转载自westboy172887564.iteye.com/blog/1820265
今日推荐