U8 Cloud 当前单据和相关联单据增加并发控制

保存和删除增加并发控制

  • 技术概要

1.对当前单据增加并发锁

// 存放需要加锁的主键  表头+表体主键
ArrayList<String> lockpks = new ArrayList<>();
// 加并发锁
LockTool.setDynamicLockForPks((String[]) lockpks.toArray(new String[0]), null);
//表头校验ts
// 根据主键查询表头vo
StoreMainVO mainVO = baseDAO.queryVOByPK(StoreMainVO.class, storeMainVO.getPk_stroe_main());
if (!mainVO.getTs().equals(storeMainVO.getTs())) {
	throw new BusinessException("数据已被修改,请重新查询");
}

//表体校验ts
//修改之前的ts
	ArrayList<UFDateTime> tsList =tsList = new ArrayList<UFDateTime>();
	if (tsList != null) {
			String condition = sBuilder.toString();
			String[] fields = { "ts" };
			// 数据库表体ts
			List<UFDateTime> lastTs = new ArrayList<>();
			Collection<StoreSubVO> lbList = baseDAO.retrieveByClause(StoreSubVO.class, condition, fields);

			for (StoreSubVO temp : lbList) {
				lastTs.add(temp.getTs());
			}

			Set<UFDateTime> set1 = new HashSet<>(tsList);
			Set<UFDateTime> set2 = new HashSet<>(lastTs);
			boolean isEqual = set1.equals(set2);
			if (!isEqual) {
				throw new BusinessException("数据已被修改,请重新查询");
			}
		}

2.对当前单据关联的其他对象

//获取加锁单据的主键
//对加锁单据进行加锁
boolean lockPeriod = false;
 //如果返回值为false说明,已经被加锁了
lockPeriod = PKLock.getInstance().acquireLock(hsPk, PubEnv.getPk_user(), null);
	if (!lockPeriod) {
		throw new BusinessException(							NCLangResOnserver.getInstance().getStrByID("60131004", "UPP60131004-000303"));
	}
//校验时间戳

//进行更新操作

//解锁   放到finally{}里面,这样抛异常不影响解锁
if (lockPeriod)
PKLock.getInstance().releaseLock(hsPk, PubEnv.getPk_user(), null);

两种加锁区别
LockTool.setDynamicLockForPks((String[]) lockpks.toArray(new String[0]), null);
自动加锁自动解锁,只需要传入需要加锁的主键值数组
lockPeriod = PKLock.getInstance().acquireLock(hsPk, PubEnv.getPk_user(), null);
PKLock.getInstance().releaseLock(hsPk, PubEnv.getPk_user(), null);
手动加锁需要手动解锁,传入值为加锁pk,当前登录userId

总代码

package u8c.impl.pe;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.jfree.chart.demo.Performance;

import com.ibm.db2.jcc.sqlj.m;

import nc.bs.dao.BaseDAO;
import nc.bs.dao.DAOException;
import nc.bs.ml.NCLangResOnserver;
import nc.bs.pub.pflock.PfBusinessLock;
import nc.bs.pub.pflock.VOConsistenceCheck;
import nc.bs.pub.pflock.VOLockData;
import nc.bs.uap.lock.PKLock;
import nc.hr.utils.PubEnv;
import nc.hr.utils.ResHelper;
import nc.itf.scm.pub.lock.LockTool;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.ui.hr.frame.persistence.PersitenceDelegator;
import nc.vo.hr.tools.pub.HRAggVO;
import nc.vo.pub.AggregatedValueObject;
import nc.vo.pub.BusinessException;
import nc.vo.pub.CircularlyAccessibleValueObject;
import nc.vo.pub.SuperVO;
import nc.vo.pub.ValidationException;
import nc.vo.pub.lang.UFDateTime;
import nc.vo.pub.lang.UFDouble;
import u8c.itf.hr.lb.IOperateData;
import u8c.vo.hr.pe_001.PerformanceVO;
import u8c.vo.pe.AggStoreMainVO;
import u8c.vo.pe.StoreMainVO;
import u8c.vo.pe.StoreSubVO;

public class IOperateDataImpl implements IOperateData {
	private BaseDAO baseDao = null;

	public BaseDAO getBaseDao() {
		if (baseDao == null) {
			this.baseDao = new BaseDAO();
		}
		return baseDao;
	}

	@Override
	public Object saveEditData(Object data, String checkClassMethodName, String lockClassName) throws Exception {

		if (data instanceof HRAggVO) {
			HRAggVO hrAggVO = (HRAggVO) data;
			String hsBackfill="";
			StoreMainVO parentVO = (StoreMainVO) hrAggVO.getParentVO();
			if (parentVO.getPk_stroe_main() != null) {
				addLock(data);
			} else {
				 hsBackfill = hsBackfill(data);
			}
			parentVO.setVdef1(hsBackfill);
			hrAggVO.setParentVO(parentVO);
			/**
			 * 测试并发 UFDouble other = parentVO.getOther(); String string = other.toString();
			 * if(string.equals("1.00")) { try { Thread.sleep(10000); } catch
			 * (InterruptedException e) { // 处理中断异常 } }
			 */
			return PersitenceDelegator.saveAggVO(hrAggVO, checkClassMethodName, lockClassName);
		}
		if (data instanceof HRAggVO[]) {
			HRAggVO[] hrAggVOs = (HRAggVO[]) data;
			if (hrAggVOs != null && hrAggVOs.length > 0) {
				StoreMainVO parentVO = (StoreMainVO) hrAggVOs[0].getParentVO();
				if (parentVO.getPk_stroe_main() != null) {
					addLock(data);
				}else {
					hsBackfill(data);
				}
			}
//			addLock(data);
			return PersitenceDelegator.saveAggVOArray(hrAggVOs, checkClassMethodName, lockClassName);
		}

		return null;
	}

	public String hsBackfill(Object data) throws Exception {
		BaseDAO baseDAO = getBaseDao();
		if (data instanceof HRAggVO) {
			HRAggVO hrAggVO = (HRAggVO) data;
			StoreMainVO storeMainVO = (StoreMainVO) hrAggVO.getParentVO();
			String hsPk = storeMainVO.getPk_performance();
			String vdef1 = storeMainVO.getVdef1();
			boolean lockPeriod = false;

			try {
				lockPeriod = PKLock.getInstance().acquireLock(hsPk, PubEnv.getPk_user(), null);
				if (!lockPeriod) {
					throw new BusinessException(
							NCLangResOnserver.getInstance().getStrByID("60131004", "UPP60131004-000303"));
				}
				PerformanceVO performanceVO = baseDAO.queryVOByPK(PerformanceVO.class, storeMainVO.getPk_performance());
				if(performanceVO.getTs().equals(new UFDateTime(vdef1))) {
					String sql = "update pe_performance set iscite='1' where pk_performance='" + hsPk + "'";
					baseDAO.executeUpdate(sql);
					String selectTs="select ts from pe_performance where pk_performance='"+ hsPk + "'";
					String lastTs=(String)baseDAO.executeQuery(selectTs,new ColumnProcessor());
					return lastTs;
				}else {
					new ValidationException("数据已经被修改,请刷新界面");
				}
			
				
			} finally {
				if (lockPeriod)
					PKLock.getInstance().releaseLock(hsPk, PubEnv.getPk_user(), null);
			}
			

		}
		return null;

	}



	public void hsBackfillDel(Object data) throws BusinessException {
		BaseDAO baseDAO = getBaseDao();
		if (data instanceof HRAggVO) {
			HRAggVO hrAggVO = (HRAggVO) data;
			StoreMainVO storeMainVO = (StoreMainVO) hrAggVO.getParentVO();
			String hsPk = storeMainVO.getPk_performance();
			String vdef1 = storeMainVO.getVdef1();
			boolean lockPeriod = false;

			try {
				lockPeriod = PKLock.getInstance().acquireLock(hsPk, PubEnv.getPk_user(), null);
				if (!lockPeriod) {
					throw new BusinessException(
							NCLangResOnserver.getInstance().getStrByID("60131004", "UPP60131004-000303"));
				}
				PerformanceVO performanceVO = baseDAO.queryVOByPK(PerformanceVO.class, storeMainVO.getPk_performance());
				if(performanceVO.getTs().equals(new UFDateTime(vdef1))) {
					String sql = "update pe_performance set iscite='0' where pk_performance='" + hsPk + "'";
					baseDAO.executeUpdate(sql);
					StoreMainVO delStoreMain = delChangeStates(data);
					baseDAO.updateVO(delStoreMain, new String[] { "dr" });
				}else {
					new ValidationException("数据已经被修改,请刷新界面");
				}
			} finally {
				if (lockPeriod)
					PKLock.getInstance().releaseLock(hsPk, PubEnv.getPk_user(), null);
			}
			

		} else if (data instanceof HRAggVO[]) {
			HRAggVO[] hrAggVOs = (HRAggVO[]) data;
			boolean[] lockPeriod = new boolean[hrAggVOs.length];
			StringBuilder sBuilder = new StringBuilder("update pe_performance set iscite='0' where pk_performance in(");
			StringBuilder queryBuilder = new StringBuilder("pk_performance in(");
			
			boolean flag=true;
			ArrayList<String> unLockPk=new ArrayList<String>();
			List<UFDateTime> beforeTimes = new ArrayList<>();
			ArrayList<UFDateTime> afterTimes = new ArrayList<UFDateTime>();
			try {
				HRAggVO hrAggVO = null;
				for (int i = 0; i < hrAggVOs.length; i++) {
					lockPeriod[i]=false;
					hrAggVO=hrAggVOs[i];
					StoreMainVO storeMainVO = (StoreMainVO) hrAggVO.getParentVO();
					String hsPk = storeMainVO.getPk_performance();
					String vdef1 = storeMainVO.getVdef1();
					beforeTimes.add(new UFDateTime(vdef1));
					lockPeriod[i] = PKLock.getInstance().acquireLock(hsPk, PubEnv.getPk_user(), null);
					sBuilder.append("'").append(storeMainVO.getPk_performance()).append("',");
					queryBuilder.append("'").append(storeMainVO.getPk_performance()).append("',");
					if(!lockPeriod[i]) {
						flag=false;
					}
					unLockPk.add(hsPk);

				}
				sBuilder.setCharAt(sBuilder.length() - 1, ')');
				queryBuilder.setCharAt(queryBuilder.length() - 1, ')');
				String sql = sBuilder.toString();
				if(flag) {
					String[] fields = { "ts" };
					String condition=queryBuilder.toString();
					// 数据库表体ts
					Collection<PerformanceVO> afterSubVOs = baseDAO.retrieveByClause(PerformanceVO.class, condition, fields);

					for (PerformanceVO temp : afterSubVOs) {
						afterTimes.add(temp.getTs());
					}

					Set<UFDateTime> set1 = new HashSet<>(beforeTimes);
					Set<UFDateTime> set2 = new HashSet<>(afterTimes);
					boolean isEqual = set1.equals(set2);
					if (!isEqual) {
						throw new BusinessException("数据已被修改,请重新查询");
					}else {
						baseDAO.executeUpdate(sql);
						
						StoreMainVO[] afterAggVOs = new StoreMainVO[hrAggVOs.length];
						for (int i = 0; i < hrAggVOs.length; i++) {
							afterAggVOs[i] = delChangeStates(hrAggVOs[i]);
						}
						baseDAO.updateVOArray(afterAggVOs, new String[] { "dr" });
					}
					
					
				}else {
					throw new BusinessException(
							NCLangResOnserver.getInstance().getStrByID("60131004", "UPP60131004-000303"));
				}
				
			} finally {
				for (int i = 0; i < lockPeriod.length; i++) {
					if(lockPeriod[i]) {
						PKLock.getInstance().releaseLock(unLockPk.get(i), PubEnv.getPk_user(), null);
				
					}
				}
			}
			
		}
	}

	@Override
	public boolean deleteData(Object data, String checkClassMethodName, String lockClassName) throws Exception {
		BaseDAO baseDAO = getBaseDao();
		
		if (data instanceof HRAggVO) {
			addLock(data);
			/** 两个单据都进行并发和校验ts以后再进行数据库操作
			StoreMainVO hrAggVO = delChangeStates(data);
			baseDAO.updateVO(hrAggVO, new String[] { "dr" });
			*/
			hsBackfillDel(data);
			return true;
		}
		if (data instanceof HRAggVO[]) {
			addLock(data);
			/** 
			HRAggVO[] hrAggVOs = (HRAggVO[]) data;
			StoreMainVO[] afterAggVOs = new StoreMainVO[hrAggVOs.length];
			for (int i = 0; i < hrAggVOs.length; i++) {
				afterAggVOs[i] = delChangeStates(hrAggVOs[i]);
			}
			baseDAO.updateVOArray(afterAggVOs, new String[] { "dr" });
			*/
			hsBackfillDel(data);
			return true;
		}
		/**
		 * if (data instanceof SuperVO) { PersitenceDelegator.deleteVO((SuperVO) data,
		 * checkClassMethodName); return true; } if (data instanceof SuperVO[]) {
		 * PersitenceDelegator.deleteVOArray((SuperVO[]) data, checkClassMethodName);
		 * return true; }
		 */

		return false;
	}

	@Override
	public void importDataSave(StoreSubVO[] storeSubVOs) throws Exception {
		BaseDAO baseDAO = getBaseDao();
		addLock(storeSubVOs);
//			baseDAO.executeUpdate("update pe_store_sub set dr='1' where pk_store_sub='1002ZZ10000000001EXO' ");
		baseDAO.updateVOArray(storeSubVOs);

	}

	private StoreMainVO delChangeStates(Object data) {
		if (data instanceof HRAggVO) {
			HRAggVO hrAggVO = (HRAggVO) data;
			StoreMainVO storeMainVO = (StoreMainVO) hrAggVO.getParentVO();
			storeMainVO.setDr(1);
			hrAggVO.setParentVO(storeMainVO);
			return storeMainVO;
		}
		return null;
	}
	// 加锁并且检查时间戳

	private void addLock(Object data) throws BusinessException {
		if (data instanceof HRAggVO) {
			HRAggVO hrAggVO = (HRAggVO) data;
			addHRAggVOLock(hrAggVO);
		} else if (data instanceof HRAggVO[]) {
			HRAggVO[] hrAggVOs = (HRAggVO[]) data;
			for (int i = 0; i < hrAggVOs.length; i++) {
				addHRAggVOLock(hrAggVOs[i]);
			}
		} else if (data instanceof SuperVO) {
			StoreSubVO storeSubVO = (StoreSubVO) data;
			addSuperVOLock(storeSubVO);
		} else {
			StoreSubVO[] storeSubVOs = (StoreSubVO[]) data;
			addSuperVOsLock(storeSubVOs);
		}

	}

	// 加锁并且检查时间戳
	private void addHRAggVOLock(HRAggVO aggVO) throws BusinessException {
		BaseDAO baseDAO = getBaseDao();
		StoreMainVO storeMainVO = (StoreMainVO) aggVO.getParentVO();
		// 获取当前单据表体所有数据
		CircularlyAccessibleValueObject[] allChildrenVO = aggVO.getAllChildrenVO();
		// 存放需要加锁的主键
		ArrayList<String> lockpks = new ArrayList<>();
		StoreSubVO storeSubVO = null;

		// 表头主键
		if (!lockpks.contains(storeMainVO.getPk_stroe_main())) {
			lockpks.add(storeMainVO.getPk_stroe_main());
		}
		StringBuilder sBuilder = new StringBuilder("pk_store_sub in(");
		ArrayList<UFDateTime> tsList = null;
		if (allChildrenVO != null) {
			// 存放修改时,表体的时间戳
			tsList = new ArrayList<UFDateTime>();
			// 表体主键
			for (int i = 0; i < allChildrenVO.length; i++) {
				storeSubVO = (StoreSubVO) allChildrenVO[i];
				if (!lockpks.contains(storeSubVO.getPk_store_sub())) {
					lockpks.add(storeSubVO.getPk_store_sub());
				}
				tsList.add(storeSubVO.getTs());

				sBuilder.append("'").append(storeSubVO.getPk_store_sub()).append("',");

			}
			sBuilder.setCharAt(sBuilder.length() - 1, ')');

		}
		// 加并发锁
		LockTool.setDynamicLockForPks((String[]) lockpks.toArray(new String[0]), null);

		// 根据主键查询表头vo
		StoreMainVO mainVO = baseDAO.queryVOByPK(StoreMainVO.class, storeMainVO.getPk_stroe_main());

		if (!mainVO.getTs().equals(storeMainVO.getTs())) {
			throw new BusinessException("数据已被修改,请重新查询");
		}
		if (tsList != null) {
			String condition = sBuilder.toString();
			String[] fields = { "ts" };
			// 数据库表体ts
			List<UFDateTime> lastTs = new ArrayList<>();
			Collection<StoreSubVO> lbList = baseDAO.retrieveByClause(StoreSubVO.class, condition, fields);

			for (StoreSubVO temp : lbList) {
				lastTs.add(temp.getTs());
			}

			Set<UFDateTime> set1 = new HashSet<>(tsList);
			Set<UFDateTime> set2 = new HashSet<>(lastTs);
			boolean isEqual = set1.equals(set2);
			if (!isEqual) {
				throw new BusinessException("数据已被修改,请重新查询");
			}
		}

	}

	private void addSuperVOLock(StoreSubVO storeSubVO) throws BusinessException {
		// 存放需要加锁的主键
		ArrayList<String> lockpks = new ArrayList<>();
		// 加并发锁
		if (storeSubVO != null) {
			lockpks.add(storeSubVO.getPk_store_sub());
		}
		LockTool.setDynamicLockForPks((String[]) lockpks.toArray(new String[0]), null);
		BaseDAO baseDAO = new BaseDAO();
		StoreSubVO subVO = (StoreSubVO) baseDAO.retrieveByPK(StoreSubVO.class, storeSubVO.getPk_store_sub());
		if (!(storeSubVO.getTs().equals(subVO.getTs()))) {
			throw new BusinessException("数据已被修改,请重新查询");
		}
	}

	private void addSuperVOsLock(StoreSubVO[] storeSubVOs) throws BusinessException {

		if (storeSubVOs == null || storeSubVOs.length < 1) {
			throw new ValidationException("Excel没有任何数据导入");
		}
		BaseDAO baseDAO = getBaseDao();
//		Before and after
		List<UFDateTime> beforeTimes = new ArrayList<>();
		ArrayList<UFDateTime> afterTimes = new ArrayList<UFDateTime>();
		StringBuilder sBuilder = new StringBuilder("pk_store_sub in(");

		for (int i = 0; i < storeSubVOs.length; i++) {
			StoreSubVO storeSubVO = storeSubVOs[i];
			beforeTimes.add(storeSubVO.getTs());
			sBuilder.append("'").append(storeSubVO.getPk_store_sub()).append("',");
		}
		sBuilder.setCharAt(sBuilder.length() - 1, ')');
		String condition = sBuilder.toString();
		String[] fields = { "ts" };
		// 数据库表体ts
		Collection<StoreSubVO> afterSubVOs = baseDAO.retrieveByClause(StoreSubVO.class, condition, fields);

		for (StoreSubVO temp : afterSubVOs) {
			afterTimes.add(temp.getTs());
		}

		Set<UFDateTime> set1 = new HashSet<>(beforeTimes);
		Set<UFDateTime> set2 = new HashSet<>(afterTimes);
		boolean isEqual = set1.equals(set2);
		if (!isEqual) {
			throw new BusinessException("数据已被修改,请重新查询");
		}

	}

}

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值