工作流activiti-02事物控制、流程引擎创建
使用activiti中有个很重要的问题就是需要保证事物的控制
activiti使用的是mybatis作为orm技术 封装了一系列的操作数据库操作 这也就是大家调用的api 操作的数据库表都是activit自带的数据表 一般情况下使用spring整合
activiti的事物是很强大的 但是往往就不能如愿 因为公司使用的都是自己的框架不能利用spring来整合事物。
通过java程序来控制activiti的事物
activiti的事物依赖于TransactionFactory 在创建流程引擎ProcessEngine来指定事物工厂,其原因分析如下:
创建流程引擎: ProcessEngine processEngine = conf.buildProcessEngine() ;
conf为StandaloneProcessEngineConfiguration的对象其buildProcessEngine方法如下:
public ProcessEngine buildProcessEngine() { init(); return new ProcessEngineImpl(this); }
//调用init方法
protected void init() {
initHistoryLevel();
initExpressionManager();
initVariableTypes();
initBeans();
initFormEngines();
initFormTypes();
initScriptingEngines();
initBusinessCalendarManager();
initCommandContextFactory();
initTransactionContextFactory();
initCommandExecutors();
initServices();
initIdGenerator();
initDeployers();
initJobExecutor();
initMailScanner();
initDataSource();
initTransactionFactory();
initSqlSessionFactory();
initSessionFactories();
initJpa();
initDelegateInterceptor();
initEventHandlers();
}
其中初始化了很多信息,可以依次看看源码 其中initTransactionFactory()方法代码如下:
// myBatis SqlSessionFactory ////////////////////////////////////////////////
protected void initTransactionFactory() {
if (transactionFactory==null) {
if (transactionsExternallyManaged) {
transactionFactory = new ManagedTransactionFactory();
} else {
transactionFactory = new JdbcTransactionFactory();
}
}
}
其中transactionFactory为 protected TransactionFactory transactionFactory; 类中的属性
由代码可知 如果transactionFactory不为空则事物工厂为JdbcTransactionFactory的实例化对象
那么设置StandaloneProcessEngineConfiguration的transactionFactory的值为一JdbcTransactionFactory对象即可
代码如下:创建一个servlet监听器 在容器启动的时候创建一个流程引擎 (需要配置web.xml文件)
/********************************************************************** * <pre> * FILE : MyServletListener.java * CLASS : MyServletListener * * AUTHOR : Liaokailin * * FUNCTION : * * * Contact: Sina L凯林
* *====================================================================== * CHANGE HISTORY LOG *---------------------------------------------------------------------- * MOD. NO.| DATE | NAME | REASON | CHANGE REQ. *---------------------------------------------------------------------- * |2014年1月17日|Liaokailin| Created | * DESCRIPTION: * </pre> ***********************************************************************/ package com.infodms.dms.actions; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.activiti.engine.ProcessEngine; import org.activiti.engine.ProcessEngineConfiguration; import org.activiti.engine.ProcessEngines; import org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration; import com.infodms.dms.db.DBManager; import com.infodms.dms.utils.DmsActivitiTransactionFactory; public class MyServletListener implements ServletContextListener { @Override public void contextDestroyed(ServletContextEvent arg0) { ProcessEngines.destroy(); } @Override public void contextInitialized(ServletContextEvent arg0) { StandaloneProcessEngineConfiguration conf = (StandaloneProcessEngineConfiguration) ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration(); conf.setDataSource(DBManager.getDataSource()).setDatabaseSchemaUpdate("true").setDbHistoryUsed(true) ; conf.setTransactionFactory(new DmsActivitiTransactionFactory()) ; ProcessEngine processEngine = conf.buildProcessEngine() ; } }
conf.setTransactionFactory(new DmsActivitiTransactionFactory()) ;设置事物
DmsActivitiTransactionFactory代码如下:
/********************************************************************** * <pre> * FILE : DmsActivitiTransactionFactory.java * CLASS : DmsActivitiTransactionFactory * * AUTHOR : Liaokailin * * FUNCTION : * * * Contact: Sina L凯林
* *====================================================================== * CHANGE HISTORY LOG *---------------------------------------------------------------------- * MOD. NO.| DATE | NAME | REASON | CHANGE REQ. *---------------------------------------------------------------------- * |2014年1月21日|Liaokailin| Created | * DESCRIPTION: * </pre> ***********************************************************************/ package com.infodms.dms.utils; import java.sql.Connection; import java.util.Properties; import org.apache.ibatis.transaction.Transaction; import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; import com.infoservice.po3.core.context.DBService; public class DmsActivitiTransactionFactory extends JdbcTransactionFactory { @Override public Transaction newTransaction(Connection conn, boolean autoCommit) { System.out.println("开启新的事物"); return new DmsActitiviTransaction(conn,autoCommit) ; //return (Transaction) DBService.getInstance().getTransaction() ; } @Override public void setProperties(Properties props) { super.setProperties(props); } }
DmsActitiviTransaction 代码如下:
/********************************************************************** * <pre> * FILE : DmsActitiviTransaction.java * CLASS : DmsActitiviTransaction * * AUTHOR : Liaokailin * * FUNCTION : * * * Contact: Sina L凯林 * *====================================================================== * CHANGE HISTORY LOG *---------------------------------------------------------------------- * MOD. NO.| DATE | NAME | REASON | CHANGE REQ. *---------------------------------------------------------------------- * |2014年1月21日|Liaokailin| Created | * DESCRIPTION: * </pre> ***********************************************************************/ package com.infodms.dms.utils; import java.sql.Connection; import java.sql.SQLException; import org.apache.ibatis.transaction.jdbc.JdbcTransaction; import com.infodms.dms.db.DBManager; import com.infoservice.po3.core.context.DBService; public class DmsActitiviTransaction extends JdbcTransaction { private static Connection conn = null ; public DmsActitiviTransaction(Connection connection, boolean desiredAutoCommit) { //connection.setAutoCommit(desiredAutoCommit); super(connection, desiredAutoCommit); try { connection.setAutoCommit(desiredAutoCommit); } catch (SQLException e) { e.printStackTrace(); } } @Override public Connection getConnection() { /*DBService d = DBService.getInstance() ; d.loadConf("/DataAccessContext.xml"); return d.getConnection() ;*/ // return DBService.getInstance().getConnection() ; try { if(conn==null){ synchronized (DmsActitiviTransaction.class) { conn = DBManager.getConnection() ; } } return conn ; } catch (Exception e) { System.out.println("获取链接失败:"+e); return null ; } } @Override public void close() throws SQLException { /* if(conn!=null&&!conn.isClosed()){ conn.close(); }*/ System.out.println("activit:close()"); } @Override public void commit() throws SQLException { /*if(conn!=null&&!conn.isClosed()){ conn.commit(); }*/ System.out.println("activit:commit()"); } @Override protected void resetAutoCommit() { System.out.println("resetAutoCommit()"); /*try { if (conn != null && !conn.isClosed()) { conn.setAutoCommit(false); } } catch (SQLException e) { e.printStackTrace(); }*/ } @Override public void rollback() throws SQLException { /*if(conn!=null&&!conn.isClosed()){ conn.rollback(); }*/ System.out.println("activit:rollback()"); } @Override protected void setDesiredAutoCommit(boolean arg0) { System.out.println("setDesiredAutoCommit:"+arg0); } }
其中DBManager
/********************************************************************** * <pre> * FILE : DBManager.java * CLASS : DBManager * * AUTHOR : Liaokailin * * FUNCTION : * * * Contact: Sina L凯林 * *====================================================================== * CHANGE HISTORY LOG *---------------------------------------------------------------------- * MOD. NO.| DATE | NAME | REASON | CHANGE REQ. *---------------------------------------------------------------------- * |2014年1月22日|Liaokailin| Created | * DESCRIPTION: * </pre> ***********************************************************************/ package com.infodms.dms.db; import java.sql.Connection; import java.sql.SQLException; import javax.sql.DataSource; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import com.infoservice.po3.core.context.DBInfo; public class DBManager { public static DataSource dataSource = null ; public static Connection conn = null ; public static DataSource getDataSource(){ if(dataSource==null){ synchronized (DBManager.class) { Resource resource = new ClassPathResource("/DataAccessContext.xml"); BeanFactory springBeanFactory = new XmlBeanFactory(resource); DBInfo dbInfo = ((DBInfo)springBeanFactory.getBean("DBInfo")); dataSource = (DataSource)springBeanFactory.getBean(dbInfo.getDefDataSource()); System.out.println("获取数据源"); } }else{ System.out.println("默认数据源调用"); } return dataSource ; } public static Connection getConnection() throws SQLException{ if(conn!=null&&!conn.isClosed()){ System.out.println("获取默认连接"); }else{ synchronized (DBManager.class) { System.out.println("获取连接"); conn = getDataSource().getConnection() ; } } return conn ; } public static void startTransaction(Connection connection) throws SQLException { System.out.println("开启事物"); connection.setAutoCommit(false); } public static void endTransaction(Connection connection) throws SQLException{ System.out.println("提交事物 "); connection.commit(); connection.setAutoCommit(true); } public static void rollBack(Connection connection) throws SQLException{ System.out.println("回滚事物"); connection.rollback(); } }
调用的使用DBManager就ok了