activiti事務和本身業務事務共同的使用

本人博客開始遷移,博客整個架構本身搭建及編碼 http://www.cookqq.com/listBlog.action  java

一個數據庫事務一般包含了一個序列的對數據庫的讀/寫操做。它的存在包含有如下兩個目的:spring

  1. 爲數據庫操做序列提供了一個從失敗中恢復到正常狀態的方法,同時提供了數據庫即便在異常狀態下仍能保持一致性的方法。sql

  2. 當多個應用程序併發訪問數據庫時,能夠在這些應用程序之間提供一個隔離方法,以防止彼此的操做互相干擾。數據庫

相信每一個項目都有本身的事務控制管理方法。可是怎麼和activiti的事務相結合使用呢? apache

activiti基於spring的事務集成網上的資料不少。這裏省略1000字。 session

可是,有的項目並無使用spring,那怎麼控制事務呢?架構

一、建立activiti的配置信息:併發


StandaloneProcessEngineConfiguration conf = (StandaloneProcessEngineConfiguration) ProcessEngineConfiguration
					.createStandaloneProcessEngineConfiguration();

二、設置activiti配置信息(好比是否自動更新,是否使用歷史,字體...): ide



conf.setDatabaseSchemaUpdate("true");
			conf.setDbHistoryUsed(true);
			conf.setHistory("full");
			conf.setActivityFontName("宋體");
			conf.setJobExecutorActivate(false);

三、設置數據庫的DataSource 字體



conf.setDataSource(DBManager.getDataSource());

請注意:這個DBManager.getDataSource()是本身封裝的代碼。


四、設置事務管理工廠(CustomJdbcTransactionFactory這個方法時我本身寫的,下面會詳細介紹):


CustomJdbcTransactionFactory jdbcTransactionFactory=
					new CustomJdbcTransactionFactory();
			conf.setTransactionFactory(jdbcTransactionFactory);

重點就是在這了。

本身的事務會開啓一個數據庫鏈接Connection conn  = dataSource.getConnection(),本身的全部操做都會在這個鏈接中完成。activiti的操做數據的時候也會打開一個鏈接dataSource.getConnection(),操做本身的數據。那就會出現問題,不在同一個鏈接中,何談事務啊?

StandaloneProcessEngineConfiguration 中有個變量事務管理器。

咱們能夠重寫事務管理器裏面打開鏈接的方法,而後再set配置對象conf中。

import java.sql.Connection;  

import java.sql.SQLException;

import javax.sql.DataSource;

import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.session.TransactionIsolationLevel;
import org.apache.ibatis.transaction.jdbc.JdbcTransaction;

import com.fangdo.core.db.DBManager;

public class CustomJdbcTransaction extends JdbcTransaction {

	private static final Log log = LogFactory.getLog(CustomJdbcTransaction.class);
	public CustomJdbcTransaction(Connection connection) {
		super(connection);
	}

	public CustomJdbcTransaction(DataSource ds,
			TransactionIsolationLevel desiredLevel, boolean desiredAutoCommit) {
		super(ds, desiredLevel, desiredAutoCommit);
	}

	@Override
	protected void openConnection() throws SQLException {
//		super.openConnection();
		connection = DBManager.getConnection();
		if (log.isDebugEnabled()) {
	      log.debug("{CustomJdbcTransaction } Openning JDBC Connection"+connection.hashCode()+"[]"+autoCommmit);
	    }
//	    connection = dataSource.getConnection();
	    if (level != null) {
	      connection.setTransactionIsolation(level.getLevel());
	    }
	    setDesiredAutoCommit(autoCommmit);
	}

	@Override
	public void close() throws SQLException {
		if (log.isDebugEnabled()) {
		      log.debug("{CustomJdbcTransaction } closing JDBC Connection"+connection.hashCode());
		    }
//		super.close();
	}

	@Override
	public void commit() throws SQLException {
		// TODO Auto-generated method stub
//		super.commit();
	}

	@Override
	public void rollback() throws SQLException {
		// TODO Auto-generated method stub
//		super.rollback();
	}
}

重寫了openConnection()方法,獲取數據庫鏈接是我業務打開的那個鏈接。

鏈接關閉close(),提交commit(),回滾rollback() ,所有註銷了。對數據庫鏈接的操做都有我業務來控制,不讓activiti控制了。

import java.sql.Connection;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.ibatis.session.TransactionIsolationLevel;
import org.apache.ibatis.transaction.Transaction;
import org.apache.ibatis.transaction.jdbc.JdbcTransaction;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;

public class CustomJdbcTransactionFactory extends JdbcTransactionFactory {

	@Override
	public void setProperties(Properties props) {
		super.setProperties(props);
	}

	@Override
	public Transaction newTransaction(Connection conn) {
//		return super.newTransaction(conn);
		return new CustomJdbcTransaction(conn);
	}

	@Override
	public Transaction newTransaction(DataSource ds,
			TransactionIsolationLevel level, boolean autoCommit) {
//		return super.newTransaction(ds, level, autoCommit);
		return new CustomJdbcTransaction(ds, level, autoCommit);
	}

}



CustomJdbcTransactionFactory就是建立工廠。很好理解。 五、建立引擎:



processEngine = conf.buildProcessEngine();

六、使用例子:



QueryHelper.startTransaction();//開啓事務
			
			taskService.claim(taskId, getPhoneId());
			taskService.complete(taskId, variables);
			。。。。。//本身的業務代碼
			QueryHelper.endTransaction();//關閉事務

本身業務和activiti共用了同一個事務,若是拋出異常,就會回滾回去了。

這裏簡單說一個,QueryHelper.startTransaction()主要作的事情:

Connection conn = dataSource.getConnection();
conn.setAutoCommit(false);



QueryHelper.endTransaction()主要作的事情是:

Connection connection = getConnection();
			connection.commit();//提交JDBC事務   
			connection.setAutoCommit(true);// 恢復JDBC事務的默認提交方式



 getConnection()這個方法獲取的事上面開啓事務的哪個鏈接。

相關文章
相關標籤/搜索