You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
FZ/lis-component-lock-bl/src/main/java/com/sinosoft/lis/pubfun/PubConcurrencyLock.java

666 lines
19 KiB

package com.sinosoft.lis.pubfun;
import com.sinosoft.lis.i18n.I18nMessage;
import com.sinosoft.lis.sql.repository.LDSysVarSQL;
import com.sinosoft.lis.sql.repository.LockAppGroupSQL;
import com.sinosoft.lis.sql.repository.LockConfigSQL;
import com.sinosoft.persistence.SQLProxy;
import com.sinosoft.lis.db.LockAppGroupDB;
import com.sinosoft.lis.db.UnLockLogDB;
import com.sinosoft.lis.schema.LockAppGroupSchema;
import com.sinosoft.lis.schema.UnLockLogSchema;
import com.sinosoft.lis.vschema.LockAppGroupSet;
import com.sinosoft.lis.vschema.LockConfigSet;
import com.sinosoft.service.BusinessService;
import com.sinosoft.utility.CError;
import com.sinosoft.utility.CErrors;
import com.sinosoft.utility.DBConnPool;
import com.sinosoft.utility.ExeSQL;
import com.sinosoft.utility.SQLwithBindVariables;
import com.sinosoft.utility.SSRS;
import com.sinosoft.utility.TransferData;
import com.sinosoft.utility.VData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.Connection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
/**
* <p>
* Title:公共并发控制程序
* </p>
* <p>
* Description: 主要控制点并发
* </p>
* <p>
* Copyright: Copyright (c) 2008
* </p>
* <p>
* Company: SinoSoft
* </p>
*
* @author tongmeng
* @version 1.0
*/
public class PubConcurrencyLock implements BusinessService{
LockConfigSQL lockConfigSQL = SQLProxy.getInstance(LockConfigSQL.class);
private static final Logger logger = LoggerFactory.getLogger(PubConcurrencyLock.class);
public CErrors mErrors = new CErrors(); // 错误信息
private Connection con;
// private String mReason = "锁定应用模块不明确!";
// 保存已经锁定的业务
private TransferData mLockTransferData = new TransferData();
//tongmeng 2008-10-20 modify
//使用hashtable控制解锁.
private Hashtable mLockHashtable = new Hashtable();
private String mOpeartor = "AutoLock";
private ExeSQL mExeSQL = new ExeSQL();
public PubConcurrencyLock() {
}
/**
* 锁表操作
*
* @param conn
* @param tOperatedNo
* @return
*/
public boolean pareLockData(Connection conn, String tOperatedNo,
String tLockModule) {
String tMakeDate = PubFun.getCurrentDate();
String tMakeTime = PubFun.getCurrentTime();
try {
LockAppGroupSchema tLockAppGroupSchema = new LockAppGroupSchema();
LockAppGroupSet tLockAppGroupSet = new LockAppGroupSet();
// 获取当前业务模块所属的并发控制组.
LockConfigSet tLockConfigSet = new LockConfigSet();
tLockConfigSet = this.getLockConfig(conn, tLockModule);
if (tLockConfigSet.size() <= 0) {
// 没有为模块配置并发控制组.不做锁定,直接返回true;
logger.debug("没有配置并发控制组,不做锁定");
return true;
}
for (int i = 1; i <= tLockConfigSet.size(); i++) {
LockAppGroupDB tLockAppGroupDB = new LockAppGroupDB(conn);
tLockAppGroupDB.setOperatedNo(tOperatedNo);
tLockAppGroupDB.setLockGroup(tLockConfigSet.get(i)
.getLockGroup());
tLockAppGroupDB.setState("1");
tLockAppGroupDB.setOperator(mOpeartor);
tLockAppGroupDB.setReason(tLockModule);
tLockAppGroupDB.setMakeDate(tMakeDate);
tLockAppGroupDB.setMakeTime(tMakeTime);
tLockAppGroupDB.setModifyDate(tMakeDate);
tLockAppGroupDB.setModifyTime(tMakeTime);
if (!tLockAppGroupDB.insert()) {
CError.buildErr(this, new I18nMessage("业务号{0}所属业务组{1}当前被锁定,请稍后重试!", "LIS-11180" , tOperatedNo, tLockConfigSet.get(i).getLockGroup()));
// 插入失败,认为已经被锁定
// 在外面做连接关闭和回滚操作
// 清除所有和tLockModule 有关的数据
//tongmeng 2008-10-20 modify
//使用hashtable
Enumeration eKey=mLockHashtable.keys();
while(eKey.hasMoreElements())
{
String key=(String)eKey.nextElement();
String tValue = (String)mLockHashtable.get(key);
if ((tValue).equals(tLockModule + tOperatedNo)) {
mLockHashtable.remove(key);
}
}
// Vector tLockClear = this.mLockTransferData.getValueNames();
// for (int n = 0; n < tLockClear.size(); n++) {
// String tGroupModuleNo = (String) tLockClear.get(n);
// String tempModule = (String) this.mLockTransferData
// .getValueByName(tGroupModuleNo);
// if ((tempModule).equals(tLockModule + tOperatedNo)) {
// this.mLockTransferData.removeByName(tGroupModuleNo);
// }
// }
return false;
}
// 锁定成功,将锁定成功的业务号和业务组保存起来,便于后面解锁
//tongmeng 2008-10-20 modify
//使用hashtable
this.mLockHashtable.put(tOperatedNo + ":" + tLockConfigSet.get(i).getLockGroup(), tLockModule + tOperatedNo);
// this.mLockTransferData.setNameAndValue(tOperatedNo + ":"
// + tLockConfigSet.get(i).getLockGroup(), tLockModule
// + tOperatedNo);
}
} catch (Exception ex) {
CError.buildErr(this, new I18nMessage( ex.toString(), null));
return false;
}
return true;
}
/**
* 解锁操作
*
* @param conn
* @return
*/
public boolean pareUnLockData(Connection conn) {
try {
//tongmeng 2008-10-20 modify
//使用hashtable
Enumeration eKey=mLockHashtable.keys();
while(eKey.hasMoreElements())
{
String key=(String)eKey.nextElement();
String tValue = (String)mLockHashtable.get(key);
//获取后从hashtable中移除 add by wk
mLockHashtable.remove(key);
String[] tempNo = key.split(":");
String tOperatedNo = tempNo[0];
String tGroupNo = tempNo[1];
LockAppGroupDB tLockAppGroupDB = new LockAppGroupDB(conn);
tLockAppGroupDB.setOperatedNo(tOperatedNo);
tLockAppGroupDB.setLockGroup(tGroupNo);
if (!tLockAppGroupDB.delete()) {
// 在外面做连接关闭和回滚操作
return false;
}
}
// Vector tLockGroup = this.mLockTransferData.getValueNames();
// for (int i = 0; i < tLockGroup.size(); i++) {
// String tGroupModuleNo = (String) tLockGroup.get(i);
// String[] tempNo = tGroupModuleNo.split(":");
// String tOperatedNo = tempNo[0];
// String tGroupNo = tempNo[1];
// LockAppGroupDB tLockAppGroupDB = new LockAppGroupDB(conn);
// tLockAppGroupDB.setOperatedNo(tOperatedNo);
// tLockAppGroupDB.setLockGroup(tGroupNo);
//
// if (!tLockAppGroupDB.delete()) {
// // 在外面做连接关闭和回滚操作
// return false;
// }
// //this.mLockTransferData.removeByName(tGroupModuleNo);
// }
} catch (Exception ex) {
CError.buildErr(this, new I18nMessage( ex.toString(), null));
return false;
}
return true;
}
public boolean pareUnLockData(Connection conn,String tOperatedNo,String tLockModule) {
try {
SSRS tSSRS = lockConfigSQL.getLockGroupByLockModule(tLockModule);
if(tSSRS != null && tSSRS.getMaxRow()>0){
for(int i = 1;i<=tSSRS.getMaxRow(); i++){
String tGroupNo = tSSRS.GetText(i, 1);
LockAppGroupDB tLockAppGroupDB = new LockAppGroupDB(conn);
tLockAppGroupDB.setOperatedNo(tOperatedNo);
tLockAppGroupDB.setLockGroup(tGroupNo);
if (!tLockAppGroupDB.delete()) {
return false;
}
}
}
} catch (Exception ex) {
CError.buildErr(this, new I18nMessage( ex.toString(), null));
return false;
}
return true;
}
/**
* 按照传入的并发模块获取所有并发控制组
*
* @param tLockModule
* @return
*/
private LockConfigSet getLockConfig(Connection conn, String tLockModule) {
LockConfigSet tLockConfigSet = new LockConfigSet();
// 为了降低死锁出现的可能性,查询配置表时按照并发控制组排序
tLockConfigSet = lockConfigSQL.findAllByLockModuleOrderByLockGroup(tLockModule);
return tLockConfigSet;
}
/**
* 解锁操作
*
* @return
*/
public boolean unLock() {
con = DBConnPool.getConnection();
if (con == null) {
// @@错误处理
CError.buildErr(this, new I18nMessage("数据库连接失败!", "LIS-06519"));
return false;
}
// 设置为非自动提交
try {
con.setAutoCommit(false);
if (!pareUnLockData(con)) {
con.rollback();
con.close();
return false;
}
con.commit();
con.close();
} catch (Exception ex) {
CError.buildErr(this, new I18nMessage( ex.toString(), null));
try {
// 如果发生异常以后,关闭连接
if (con != null) {
con.rollback();
con.close();
}
} catch (Exception e) {
}
return false;
}
return true;
}
/**
* 锁定业务号
*
* @param tOperatedNo
* 业务号
* @param tLockModule
* 模块名
* @return
*/
public boolean lock(String tOperatedNo, String tLockModule) {
try {
con = DBConnPool.getConnection();
if (con == null) {
// @@错误处理
CError.buildErr(this, new I18nMessage("数据库连接失败!", "LIS-06519"));
return false;
}
// 设置为非自动提交
con.setAutoCommit(false);
if (!pareLockData(con, tOperatedNo, tLockModule)) {
con.rollback();
con.close();
return false;
}
con.commit();
con.close();
} catch (Exception ex) {
CError.buildErr(this, new I18nMessage( ex.toString(), null));
try {
// 如果发生异常以后,关闭连接
if (con != null) {
con.rollback();
con.close();
}
} catch (Exception e) {
}
return false;
}
return true;
}
/**
* 锁定业务号
*
* @param tOperatedNo
* @param tLockModule
* @param tOperator
* @return
*/
public boolean lock(String tOperatedNo, String tLockModule, String tOperator) {
try {
mOpeartor = tOperator;
con = DBConnPool.getConnection();
if (con == null) {
// @@错误处理
CError.buildErr(this, new I18nMessage("数据库连接失败!", "LIS-06519"));
return false;
}
// 设置为非自动提交
con.setAutoCommit(false);
if (!pareLockData(con, tOperatedNo, tLockModule)) {
con.rollback();
con.close();
return false;
}
con.commit();
con.close();
} catch (Exception ex) {
CError.buildErr(this, new I18nMessage( ex.toString(), null));
try {
// 如果发生异常以后,关闭连接
if (con != null) {
con.rollback();
con.close();
}
} catch (Exception e) {
}
return false;
}
return true;
}
public boolean lock(List tOperatedNo, String tLockModule, String tOperator) {
HashSet set=new HashSet();
set.addAll(tOperatedNo);
return lock(set, tLockModule, tOperator);
}
public boolean lock(HashSet tOperatedNo, String tLockModule, String tOperator) {
try {
mOpeartor = tOperator;
con = DBConnPool.getConnection();
if (con == null) {
// @@错误处理
CError.buildErr(this, new I18nMessage("数据库连接失败!", "LIS-06519"));
return false;
}
// 设置为非自动提交
con.setAutoCommit(false);
for (Iterator iterator = tOperatedNo.iterator(); iterator.hasNext();) {
String str = (String) iterator.next();
if (!pareLockData(con, str, tLockModule)) {
con.rollback();
con.close();
return false;
}
}
con.commit();
con.close();
} catch (Exception ex) {
CError.buildErr(this, new I18nMessage( ex.toString(), null));
try {
// 如果发生异常以后,关闭连接
if (con != null) {
con.rollback();
con.close();
}
} catch (Exception e) {
}
return false;
}
return true;
}
/**
*
* @param tOperatedNo
* @param tLockModule
* @param tOperator
* @return
*/
public boolean lock(String[] tOperatedNo, String tLockModule, String tOperator) {
HashSet set=new HashSet();
for (int i = 0; i < tOperatedNo.length; i++) {
set.add(tOperatedNo[i]);
}
return lock(set, tLockModule, tOperator);
}
/**
* 手动解锁 主要是为了解决系统异常终止造成的死锁.
*
* @param tOperatedNo
* @param tLockGroup
* @param tOperator
* @param tReason
* @return
*/
public boolean unLockManual(String tOperatedNo, String tLockGroup,
String tOperator, String tReason) {
try {
mOpeartor = tOperator;
// 获得连接
con = DBConnPool.getConnection();
if (con == null) {
// @@错误处理
CError.buildErr(this, new I18nMessage("数据库连接失败!", "LIS-06519"));
return false;
}
// 设置为非自动提交
con.setAutoCommit(false);
// 开始解锁操作
if (!prepareUnLockManual(con, tOperatedNo, tLockGroup, tOperator,
tReason)) {
con.rollback();
con.close();
}
con.commit();
con.close();
} catch (Exception ex) {
CError.buildErr(this, new I18nMessage( ex.toString(), null));
try {
// 如果发生异常以后,关闭连接
if (con != null) {
con.rollback();
con.close();
}
} catch (Exception e) {
}
return false;
}
return true;
}
/**
* 手工解锁业务处理
*
* @param tOperatedNo
* @param tLockGroup
* @param tOperator
* @param tReason
* @return
*/
private boolean prepareUnLockManual(Connection conn, String tOperatedNo,
String tLockGroup, String tOperator, String tReason) {
try {
// 1-查询是否有要锁定的锁表记录
LockAppGroupDB tLockAppGroupDB = new LockAppGroupDB(conn);
tLockAppGroupDB.setLockGroup(tLockGroup);
tLockAppGroupDB.setOperatedNo(tOperatedNo);
String tMakeDate = PubFun.getCurrentDate();
String tMakeTime = PubFun.getCurrentTime();
if (!tLockAppGroupDB.getInfo()) {
// 如果查询无结果
CError.buildErr(this, new I18nMessage("没有需要解锁的数据!", "LIS-11181"));
return false;
} else {
LockAppGroupSQL lockAppGroupSQL = SQLProxy.getInstance(LockAppGroupSQL.class);
LockAppGroupDB tempLockAppGroupDB = new LockAppGroupDB(conn);
LockAppGroupSet tempLockAppGroupSet = new LockAppGroupSet();
LockAppGroupSchema tempLockAppGroupSchema = new LockAppGroupSchema();
tempLockAppGroupSet = lockAppGroupSQL.findAllByOperatedNoAndLockGroupForUpdate(tOperatedNo,tLockGroup);
// 因为是按照主键查询,所以只会有一条记录对应
tempLockAppGroupSchema = tempLockAppGroupSet.get(1);
// 备份删除日志
UnLockLogSchema tBakUnLockLogSchema = new UnLockLogSchema();
UnLockLogDB tBakUnLockLogDB = new UnLockLogDB(conn);
String tIDX = PubFun1.CreateMaxNo("UNLOCKIDX", 20);
tBakUnLockLogSchema.setIDX(tIDX);
tBakUnLockLogSchema.setOperatedNo(tempLockAppGroupSchema
.getOperatedNo());
tBakUnLockLogSchema.setLockGroup(tempLockAppGroupSchema
.getLockGroup());
tBakUnLockLogSchema.setOperator(this.mOpeartor);
tBakUnLockLogSchema.setLockDate(tempLockAppGroupSchema
.getMakeDate());
tBakUnLockLogSchema.setLockTime(tempLockAppGroupSchema
.getMakeTime());
tBakUnLockLogSchema.setUnLockDate(tMakeDate);
tBakUnLockLogSchema.setUnLockTime(tMakeTime);
tBakUnLockLogSchema.setUnLockReason(tReason);
tBakUnLockLogSchema.setMakeDate(tMakeDate);
tBakUnLockLogSchema.setMakeTime(tMakeTime);
tBakUnLockLogSchema.setModifyDate(tMakeDate);
tBakUnLockLogSchema.setModifyTime(tMakeTime);
tBakUnLockLogDB.setSchema(tBakUnLockLogSchema);
if (!tBakUnLockLogDB.insert()) {
CError.buildErr(this, new I18nMessage("操作号:{0}备份数据失败!", "LIS-11183" , tOperatedNo));
return false;
}
// 删除解锁数据
tempLockAppGroupDB.setSchema(tempLockAppGroupSchema);
if (!tempLockAppGroupDB.delete()) {
CError.buildErr(this, new I18nMessage("操作号:{0}删除数据失败!", "LIS-11184" , tOperatedNo));
return false;
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
logger.error("程序执行异常",e);
return false;
}
return true;
}
/**
* 查询所有"超时"的锁表数据
*
* @return LockAppGroupSet
*/
public static LockAppGroupSet getAllTimeOutLockData() {
LockAppGroupSet tLockAppGroupSet = new LockAppGroupSet();
LockAppGroupDB tLockAppGroupDB = new LockAppGroupDB();
String tCurrDate = PubFun.getCurrentDate();
String tCurrTime = PubFun.getCurrentTime();
int tDefTimeOut = 0;
LDSysVarSQL sysVarSQL = SQLProxy.getInstance(LDSysVarSQL.class);
String tResult = sysVarSQL.findSysVarValueBySysVar("MAXLOCKTIME");
if (tResult == null || tResult.equals("")) {
// 如果没有描述设成无限大
tDefTimeOut = 999999999;
} else {
tDefTimeOut = Integer.parseInt(tResult);
}
logger.debug("tDefTimeOut:" + tDefTimeOut);
LockAppGroupSQL lockAppGroupSQL = SQLProxy.getInstance(LockAppGroupSQL.class);
tLockAppGroupSet = lockAppGroupSQL.findAllByMakeDate(tCurrDate,tCurrTime,tDefTimeOut);
return tLockAppGroupSet;
}
/**
* 解锁操作
*
* @return
*/
public boolean unLockJSP(String tOperatedNo,String tLockModule) {
con = DBConnPool.getConnection();
if (con == null) {
// @@错误处理
CError.buildErr(this, new I18nMessage("数据库连接失败!", "LIS-06519"));
return false;
}
// 设置为非自动提交
try {
con.setAutoCommit(false);
if (!pareUnLockData(con,tOperatedNo,tLockModule)) {
//TODO
con.rollback();
con.close();
return false;
}
con.commit();
con.close();
} catch (Exception ex) {
CError.buildErr(this, new I18nMessage( ex.toString(), null));
try {
// 如果发生异常以后,关闭连接
if (con != null) {
con.rollback();
con.close();
}
} catch (Exception e) {
}
return false;
}
return true;
}
/**
* 查询所有锁表数据
*
* @return SSRS
*/
public static String getAllLockData() {
String tString = "";
String tCurrDate = PubFun.getCurrentDate();
String tCurrTime = PubFun.getCurrentTime();
// 业务号,并发组,锁定日期,锁定时间,已锁时间
LockAppGroupSQL lockAppGroupSQL= SQLProxy.getInstance(LockAppGroupSQL.class);
SQLwithBindVariables sqlbv4 = lockAppGroupSQL.findOperatedNoAndLockGroupAndMakeDateAndMakeTime(tCurrDate,tCurrTime);
tString = (new ExeSQL()).getEncodedResult(sqlbv4);
return tString;
}
/**
* 传输数据的公共方法
*/
public boolean submitData(VData cInputData, String cOperate) {
boolean operFlag = false;
TransferData mTransferData = cInputData.get(TransferData.class, 0);
//通过cOperate 获取要调用的方法
if("lock3String".equalsIgnoreCase(cOperate)){
//准备传递参数
String tOperatedNo=(String)mTransferData.getValueByName("OperatedNo");
String tLockModule=(String)mTransferData.getValueByName("LockModule");
String tOperator=(String)mTransferData.getValueByName("Operator");
operFlag = this.lock(tOperatedNo, tLockModule, tOperator);
}else if("unLock".equalsIgnoreCase(cOperate)){
operFlag = this.unLock();
}else if("unLockJSP".equalsIgnoreCase(cOperate)){
String tOperatedNo=(String)mTransferData.getValueByName("OperatedNo");
String tLockModule=(String)mTransferData.getValueByName("LockModule");
if(tOperatedNo == null || tOperatedNo.equals("")||tLockModule==null ||tLockModule.equals("")){
CError.buildErr(this, new I18nMessage("需解锁的业务号码传输不完整!", "LIS-11185"));
return false;
}
operFlag = this.unLockJSP(tOperatedNo,tLockModule);
}
if(operFlag){
return true;
}else{
return false;
}
}
public CErrors getErrors() {
// TODO Auto-generated method stub
return this.mErrors;
}
public VData getResult() {
// TODO Auto-generated method stub
return null;
}
}