Commit 09990a2a authored by 雍欢's avatar 雍欢

0、CommonDomainService.move 使用jpa的方式修改实体状态,从而避免在MySQL数据库下面出现竞争version表;

1、ActApplicationImpl获取版本号的时候使用GeneralRepositorySuper.getVersionNextId,避免死锁version表
parent 439659b0
package com.huigou.data.domain.service; package com.huigou.data.domain.service;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import com.huigou.context.MessageSourceContext; import com.huigou.context.MessageSourceContext;
import com.huigou.data.domain.EntityUtil; import com.huigou.data.domain.EntityUtil;
import com.huigou.data.domain.model.*; import com.huigou.data.domain.model.AbstractEntity;
import com.huigou.data.domain.model.BaseInfoAbstractEntity;
import com.huigou.data.domain.model.BaseInfoStatus;
import com.huigou.data.domain.model.BaseInfoWithFolderAbstractEntity;
import com.huigou.data.domain.model.CommonDomainConstants;
import com.huigou.data.domain.model.FlowBillAbstractEntity;
import com.huigou.data.domain.model.MessageConstants;
import com.huigou.data.domain.model.TreeEntity;
import com.huigou.data.domain.query.CheckBaseInfoDuplicateParameter; import com.huigou.data.domain.query.CheckBaseInfoDuplicateParameter;
import com.huigou.data.domain.query.QueryParameter; import com.huigou.data.domain.query.QueryParameter;
import com.huigou.data.query.executor.SQLExecutorDao; import com.huigou.data.query.executor.SQLExecutorDao;
...@@ -10,18 +31,6 @@ import com.huigou.data.query.model.QueryDescriptor; ...@@ -10,18 +31,6 @@ import com.huigou.data.query.model.QueryDescriptor;
import com.huigou.data.repository.GeneralRepositorySuper; import com.huigou.data.repository.GeneralRepositorySuper;
import com.huigou.domain.IdentifiedEntity; import com.huigou.domain.IdentifiedEntity;
import com.huigou.util.StringUtil; import com.huigou.util.StringUtil;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** /**
* 通用领域服务 * 通用领域服务
...@@ -80,7 +89,7 @@ public class CommonDomainService { ...@@ -80,7 +89,7 @@ public class CommonDomainService {
CriteriaBuilder cb = generalRepository.getCriteriaBuilder(); CriteriaBuilder cb = generalRepository.getCriteriaBuilder();
CriteriaQuery<Integer> query = cb.createQuery(Integer.class); CriteriaQuery<Integer> query = cb.createQuery(Integer.class);
Root<?> root = query.from(clazz); Root<?> root = query.from(clazz);
query.select(cb.max(root.<Integer>get(CommonDomainConstants.SEQUENCE_FIELD_NAME))); query.select(cb.max(root.get(CommonDomainConstants.SEQUENCE_FIELD_NAME)));
if (!StringUtil.isBlank(parentIdFieldName)) { if (!StringUtil.isBlank(parentIdFieldName)) {
query.where(cb.equal(root.get(parentIdFieldName), parentId)); query.where(cb.equal(root.get(parentIdFieldName), parentId));
} }
...@@ -96,23 +105,25 @@ public class CommonDomainService { ...@@ -96,23 +105,25 @@ public class CommonDomainService {
* @param parentId 父ID * @param parentId 父ID
* @param ids ID列表 * @param ids ID列表
*/ */
@Transactional @Transactional(rollbackFor = RuntimeException.class)
public void move(Class<? extends AbstractEntity> clazz, List<String> ids, String parentIdFieldName, String parentId) { public void move(Class<? extends AbstractEntity> clazz, List<String> ids, String parentIdFieldName, String parentId) {
Assert.notNull(clazz, MessageSourceContext.getMessage(MessageConstants.CLAZZ_NOT_NULL)); Assert.notNull(clazz, MessageSourceContext.getMessage(MessageConstants.CLAZZ_NOT_NULL));
Assert.notEmpty(ids, MessageSourceContext.getMessage(MessageConstants.ID_NOT_BLANK)); Assert.notEmpty(ids, MessageSourceContext.getMessage(MessageConstants.ID_NOT_BLANK));
Assert.hasText(parentIdFieldName, MessageSourceContext.getMessage(MessageConstants.PARENT_ID_FIELD_NAME_NOT_BLANK)); Assert.hasText(parentIdFieldName, MessageSourceContext.getMessage(MessageConstants.PARENT_ID_FIELD_NAME_NOT_BLANK));
Assert.hasText(parentId, MessageSourceContext.getMessage(MessageConstants.PARENT_ID_NOT_BLANK)); Assert.hasText(parentId, MessageSourceContext.getMessage(MessageConstants.PARENT_ID_NOT_BLANK));
// update %s set %s = :parentId, version = (select next_sequence('version_seq')) where id in :ids
String tableName = EntityUtil.getTableName(clazz); String jpql = new StringBuilder("update ")
String sql = this.getSqlByName("moveSqlByParentId"); .append(clazz.getName())
sql = String.format(sql, tableName, parentIdFieldName); .append(" set ")
.append(parentIdFieldName)
Map<String, Object> params = new HashMap<String, Object>(2); .append("=:parentId,version=:version where id=:id")
.toString();
params.put(CommonDomainConstants.PARENT_ID_FIELD_NAME, parentId); ids.forEach(id -> generalRepository.getEntityManager()
params.put(CommonDomainConstants.IDS_FIELD_NAME, ids); .createQuery(jpql)
.setParameter("parentId", parentId)
this.generalRepository.updateByNativeSql(sql, params); .setParameter("version", generalRepository.getVersionNextId())
.setParameter("id", id)
.executeUpdate());
} }
/** /**
...@@ -245,40 +256,34 @@ public class CommonDomainService { ...@@ -245,40 +256,34 @@ public class CommonDomainService {
return this.generalRepository.query(jpql, params); return this.generalRepository.query(jpql, params);
} }
@Transactional(rollbackFor = RuntimeException.class, propagation = Propagation.REQUIRES_NEW) @Transactional(rollbackFor = RuntimeException.class)
public void updateSequence(Class<? extends AbstractEntity> clazz, Map<String, Integer> params) { public void updateSequence(Class<? extends AbstractEntity> clazz, Map<String, Integer> params) {
Assert.notNull(clazz, MessageSourceContext.getMessage(MessageConstants.CLAZZ_NOT_NULL)); Assert.notNull(clazz, MessageSourceContext.getMessage(MessageConstants.CLAZZ_NOT_NULL));
Assert.notEmpty(params, MessageSourceContext.getMessage(MessageConstants.PARAMETER_NOT_NULL_FORMAT, "params")); Assert.notEmpty(params, MessageSourceContext.getMessage(MessageConstants.PARAMETER_NOT_NULL_FORMAT, "params"));
for (String id : params.keySet()) {
String tableName = EntityUtil.getTableName(clazz); Integer sequence = params.get(id);
String jpql = this.getSqlByName("updateSequenceSql"); String jpql = new StringBuilder("update ")
jpql = String.format(jpql, tableName); .append(clazz.getName())
.append(" set sequence=:sequence,version=:version where id=:id")
Map<String, Object> parameterMap = new HashMap<String, Object>(2); .toString();
for (String key : params.keySet()) { int affectedRows = generalRepository.getEntityManager().createQuery(jpql)
parameterMap.put(CommonDomainConstants.ID_FIELD_NAME, key); .setParameter(CommonDomainConstants.SEQUENCE_FIELD_NAME, sequence)
parameterMap.put(CommonDomainConstants.SEQUENCE_FIELD_NAME, params.get(key)); .setParameter("version", generalRepository.getVersionNextId())
this.generalRepository.updateByNativeSql(jpql, parameterMap); .setParameter("id", id)
.executeUpdate();
Assert.isTrue(affectedRows <= 1, String.format("根据主键[%s]修改排序号出错,匹配到 %d 条数据", id, affectedRows));
} }
} }
public void updateStatus(Class<? extends AbstractEntity> clazz, List<String> ids, Integer status) { public void updateStatus(Class<? extends AbstractEntity> clazz, List<String> ids, Integer status) {
Assert.notNull(clazz, MessageSourceContext.getMessage(MessageConstants.CLAZZ_NOT_NULL)); ids.forEach(id -> updateStatusInternal(clazz, id, status));
Assert.notEmpty(ids, MessageSourceContext.getMessage(MessageConstants.ID_NOT_BLANK));
Assert.notNull(status, MessageSourceContext.getMessage(MessageConstants.STATUS_NOT_BLANK));
String tableName = EntityUtil.getTableName(clazz);
String jpql = this.getSqlByName("updateStatusesSql");
jpql = String.format(jpql, tableName);
Map<String, Object> parameterMap = new HashMap<String, Object>(2);
parameterMap.put(CommonDomainConstants.STATUS_FIELD_NAME, status);
parameterMap.put(CommonDomainConstants.IDS_FIELD_NAME, ids);
this.generalRepository.updateByNativeSql(jpql, parameterMap);
} }
public void updateStatus(Class<? extends AbstractEntity> clazz, String id, Integer status) { public void updateStatus(Class<? extends AbstractEntity> clazz, String id, Integer status) {
updateStatusInternal(clazz, id, status);
}
private void updateStatusInternal(Class<? extends AbstractEntity> clazz, String id, Integer status) {
Assert.notNull(id, MessageSourceContext.getMessage(MessageConstants.ID_NOT_BLANK)); Assert.notNull(id, MessageSourceContext.getMessage(MessageConstants.ID_NOT_BLANK));
Assert.notNull(status, MessageSourceContext.getMessage(MessageConstants.STATUS_NOT_BLANK)); Assert.notNull(status, MessageSourceContext.getMessage(MessageConstants.STATUS_NOT_BLANK));
String jpql = new StringBuilder("update ") String jpql = new StringBuilder("update ")
...@@ -347,10 +352,13 @@ public class CommonDomainService { ...@@ -347,10 +352,13 @@ public class CommonDomainService {
Assert.notNull(entity, MessageSourceContext.getMessage(MessageConstants.OBJECT_NOT_NULL)); Assert.notNull(entity, MessageSourceContext.getMessage(MessageConstants.OBJECT_NOT_NULL));
Assert.notNull(repository, MessageSourceContext.getMessage(MessageConstants.REPOSITORY_NOT_NULL)); Assert.notNull(repository, MessageSourceContext.getMessage(MessageConstants.REPOSITORY_NOT_NULL));
if (entity.isNew()) { if (entity.isNew()) {
String tableName = EntityUtil.getTableName(entity.getClass()); String jpql = new StringBuilder("select count(e) from ")
String sql = this.getSqlByName("countByBillCodeSql"); .append(entity.getClass().getName())
sql = String.format(sql, tableName); .append(" e where billCode=:billCode")
Integer count = this.sqlExecutorDao.queryToInt(sql, entity.getBillCode()); .toString();
int count = (int) generalRepository.getEntityManager().createQuery(jpql)
.setParameter("billCode", entity.getBillCode())
.getSingleResult();
Assert.isTrue(count == 0, MessageSourceContext.getMessage(MessageConstants.BILLCODE_NOT_DUPLICATE)); Assert.isTrue(count == 0, MessageSourceContext.getMessage(MessageConstants.BILLCODE_NOT_DUPLICATE));
if (entity.getStatusId() == null) { if (entity.getStatusId() == null) {
entity.setStatusId(0); entity.setStatusId(0);
......
...@@ -23,7 +23,6 @@ import com.huigou.uasp.bpm.engine.repository.HistoricProcInstanceExtensionReposi ...@@ -23,7 +23,6 @@ import com.huigou.uasp.bpm.engine.repository.HistoricProcInstanceExtensionReposi
import com.huigou.uasp.bpm.engine.repository.HistoricTaskInstanceExtensionRepository; import com.huigou.uasp.bpm.engine.repository.HistoricTaskInstanceExtensionRepository;
import com.huigou.uasp.bpm.engine.repository.HistoricTaskInstanceRelationRepository; import com.huigou.uasp.bpm.engine.repository.HistoricTaskInstanceRelationRepository;
import com.huigou.uasp.bpm.engine.repository.RuntimeTaskExtensionRepository; import com.huigou.uasp.bpm.engine.repository.RuntimeTaskExtensionRepository;
import com.huigou.uasp.bpm.managment.application.ProcDefinitionApplication;
import com.huigou.util.*; import com.huigou.util.*;
import org.activiti.engine.impl.context.Context; import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.persistence.entity.HistoricProcessInstanceEntity; import org.activiti.engine.impl.persistence.entity.HistoricProcessInstanceEntity;
...@@ -43,25 +42,16 @@ public class ActApplicationImpl extends BaseApplication implements ActApplicatio ...@@ -43,25 +42,16 @@ public class ActApplicationImpl extends BaseApplication implements ActApplicatio
*/ */
@Autowired @Autowired
private WorkflowApplication workflowService; private WorkflowApplication workflowService;
@Autowired @Autowired
private ProcUnitHandlerApplication procUnitHandlerApplication; private ProcUnitHandlerApplication procUnitHandlerApplication;
@Autowired @Autowired
private RuntimeTaskExtensionRepository runtimeTaskExtensionRepository; private RuntimeTaskExtensionRepository runtimeTaskExtensionRepository;
@Autowired @Autowired
private HistoricTaskInstanceExtensionRepository historicTaskInstExtensionRepository; private HistoricTaskInstanceExtensionRepository historicTaskInstExtensionRepository;
@Autowired @Autowired
private HistoricTaskInstanceRelationRepository historicTaskInstRelationRepository; private HistoricTaskInstanceRelationRepository historicTaskInstRelationRepository;
@Autowired @Autowired
private HistoricProcInstanceExtensionRepository historicProcInstExtensionRepository; private HistoricProcInstanceExtensionRepository historicProcInstExtensionRepository;
@Autowired
private ProcDefinitionApplication procDefinitionApplication;
@Autowired @Autowired
private ProcessFun processFun; private ProcessFun processFun;
...@@ -140,8 +130,7 @@ public class ActApplicationImpl extends BaseApplication implements ActApplicatio ...@@ -140,8 +130,7 @@ public class ActApplicationImpl extends BaseApplication implements ActApplicatio
HistoricTaskInstanceExtension historicTaskInstExtension = new HistoricTaskInstanceExtension(runtimeTaskExtension); HistoricTaskInstanceExtension historicTaskInstExtension = new HistoricTaskInstanceExtension(runtimeTaskExtension);
// 增加版本号保存 // 增加版本号保存
QueryDescriptor queryDescriptor = sqlExecutorDao.getQuery("config/uasp/query/bmp/common.xml", "common"); long version = generalRepository.getVersionNextId();
long version = sqlExecutorDao.getSqlQuery().getJDBCDao().queryToLong(String.format(queryDescriptor.getSqlByName("nextVersion")));
runtimeTaskExtension.setVersion(version); runtimeTaskExtension.setVersion(version);
runtimeTaskExtensionRepository.save(runtimeTaskExtension); runtimeTaskExtensionRepository.save(runtimeTaskExtension);
historicTaskInstExtension.setVersion(version); historicTaskInstExtension.setVersion(version);
......
...@@ -1998,7 +1998,31 @@ ...@@ -1998,7 +1998,31 @@
<name>topsunit</name> <name>topsunit</name>
<url>http://nexus.local.topsunit.com/repository/huigou-repostitory/</url> <url>http://nexus.local.topsunit.com/repository/huigou-repostitory/</url>
</repository> </repository>
<snapshotRepository>
<id>topsunit</id>
<name>topsunit SNAPSHOTS</name>
<url>http://nexus.local.topsunit.com/repository/huigou-snapshot/</url>
</snapshotRepository>
</distributionManagement> </distributionManagement>
<repositories>
<repository>
<id>huigou-public</id>
<name>huigou-public</name>
<url>http://nexus.local.topsunit.com/repository/huigou-repostitory/</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
<!-- <repository>
<id>huigou-snapshots</id>
<url>http://nexus.local.topsunit.com/repository/huigou-snapshot/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>-->
</repositories>
<build> <build>
<pluginManagement> <pluginManagement>
<plugins> <plugins>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment