废话不多说直接上代码。
1、添加maven依赖包
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-engine</artifactId>
<version>6.4.2</version>
</dependency>
2、集成核心代码
package com.nutzfw.core.plugin.flowable;
import com.nutzfw.core.plugin.flowable.transaction.NutzTransactionFactory;
import com.nutzfw.core.plugin.flowable.util.FlowStrongUuidGenerator;
import org.flowable.common.engine.impl.history.HistoryLevel;
import org.flowable.engine.*;
import org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Encoding;
import javax.sql.DataSource;
/**
* @author 黄川 huchuc@vip.qq.com
* @date: 2019/4/8
*/
@IocBean
public class FlowAbleContext {
@Inject
DataSource dataSource;
@Inject
ProcessEngine processEngine;
@IocBean
public ProcessEngine processEngine() {
ProcessEngineConfiguration engineConfiguration = new StandaloneProcessEngineConfiguration();
engineConfiguration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
engineConfiguration.setActivityFontName("宋体");
engineConfiguration.setLabelFontName("宋体");
engineConfiguration.setAnnotationFontName("宋体");
engineConfiguration.setXmlEncoding(Encoding.UTF8);
engineConfiguration.setDataSource(dataSource);
engineConfiguration.setHistoryLevel(HistoryLevel.FULL);
engineConfiguration.setIdGenerator(new FlowStrongUuidGenerator());
//设置外部管理的事务
engineConfiguration.setTransactionsExternallyManaged(true);
engineConfiguration.setTransactionFactory(new NutzTransactionFactory());
return engineConfiguration.buildProcessEngine();
}
@IocBean
public RepositoryService repositoryService() {
return processEngine.getRepositoryService();
}
@IocBean
public RuntimeService runtimeService() {
return processEngine.getRuntimeService();
}
@IocBean
public IdentityService identityService() {
return processEngine.getIdentityService();
}
@IocBean
public TaskService taskService() {
return processEngine.getTaskService();
}
@IocBean
public HistoryService historyService() {
return processEngine.getHistoryService();
}
@IocBean
public ManagementService managementService() {
return processEngine.getManagementService();
}
@IocBean
public FormService formService() {
return processEngine.getFormService();
}
@IocBean
public DynamicBpmnService dynamicBpmnService() {
return processEngine.getDynamicBpmnService();
}
}
3、我们需要在Nutz线程启用事务的时候将flowable工作流的事务管理权限交给nutz的事务,而Nutz线程没有启用事务时还是由flowable工作流自己管理
package com.nutzfw.core.plugin.flowable.transaction;
import org.apache.ibatis.session.TransactionIsolationLevel;
import org.apache.ibatis.transaction.Transaction;
import org.apache.ibatis.transaction.TransactionFactory;
import javax.sql.DataSource;
import java.sql.Connection;
import java.util.Properties;
/**
* @author 黄川 huchuc@vip.qq.com
* @date: 2019/4/19
*/
public class NutzTransactionFactory implements TransactionFactory {
@Override
public void setProperties(Properties props) {
}
@Override
public Transaction newTransaction(Connection conn) {
return new NutzTransaction(conn);
}
@Override
public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommit) {
return new NutzTransaction(ds, level, autoCommit);
}
}
package com.nutzfw.core.plugin.flowable.transaction;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.TransactionIsolationLevel;
import org.apache.ibatis.transaction.Transaction;
import org.apache.ibatis.transaction.TransactionException;
import org.nutz.trans.Trans;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
/**
* @author 黄川 huchuc@vip.qq.com
* @date: 2019/4/19
*/
@Slf4j
public class NutzTransaction implements Transaction {
private DataSource dataSource;
private TransactionIsolationLevel level;
private Connection connection;
private boolean autoCommmit;
public NutzTransaction(Connection connection) {
this.connection = connection;
}
public NutzTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommmit) {
this.dataSource = ds;
this.level = level;
this.autoCommmit = autoCommmit;
}
@Override
public Connection getConnection() throws SQLException {
if (Trans.isTransactionNone()) {
if (this.connection == null) {
openConnection();
}
} else {
this.connection = Trans.get().getConnection(dataSource);
}
return this.connection;
}
@Override
public void commit() throws SQLException {
// Does nothing
}
@Override
public void rollback() throws SQLException {
// Does nothing
}
@Override
public void close() throws SQLException {
if (this.connection != null) {
if (Trans.isTransactionNone()) {
resetAutoCommit();
if (log.isDebugEnabled()) {
log.debug("Closing JDBC Connection [" + this.connection + "]");
}
this.connection.close();
}
}
}
protected void openConnection() throws SQLException {
if (log.isDebugEnabled()) {
log.debug("Opening JDBC Connection");
}
this.connection = dataSource.getConnection();
if (level != null) {
this.connection.setTransactionIsolation(level.getLevel());
}
setDesiredAutoCommit(autoCommmit);
}
protected void setDesiredAutoCommit(boolean desiredAutoCommit) {
try {
if (connection.getAutoCommit() != desiredAutoCommit) {
if (log.isDebugEnabled()) {
log.debug("Setting autocommit to " + desiredAutoCommit + " on JDBC Connection [" + connection + "]");
}
connection.setAutoCommit(desiredAutoCommit);
}
} catch (SQLException e) {
// Only a very poorly implemented driver would fail here,
// and there's not much we can do about that.
throw new TransactionException("Error configuring AutoCommit. "
+ "Your driver may not support getAutoCommit() or setAutoCommit(). "
+ "Requested setting: " + desiredAutoCommit + ". Cause: " + e, e);
}
}
protected void resetAutoCommit() {
try {
if (!connection.getAutoCommit()) {
// MyBatis does not call commit/rollback on a connection if just selects were performed.
// Some databases start transactions with select statements
// and they mandate a commit/rollback before closing the connection.
// A workaround is setting the autocommit to true before closing the connection.
// Sybase throws an exception here.
if (log.isDebugEnabled()) {
log.debug("Resetting autocommit to true on JDBC Connection [" + connection + "]");
}
connection.setAutoCommit(true);
}
} catch (SQLException e) {
if (log.isDebugEnabled()) {
log.debug("Error resetting autocommit to true "
+ "before closing the connection. Cause: " + e);
}
}
}
@Override
public Integer getTimeout() throws SQLException {
return null;
}
}