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.
430 lines
13 KiB
430 lines
13 KiB
package com.sinosoft.lis.pubfun;
|
|
|
|
import com.sinosoft.lis.i18n.I18nMessage;
|
|
import com.sinosoft.lis.db.LockAppDB;
|
|
import com.sinosoft.lis.schema.LockAppSchema;
|
|
import com.sinosoft.lis.sql.repository.LockAppSQL;
|
|
import com.sinosoft.lis.vschema.LockAppSet;
|
|
import com.sinosoft.persistence.SQLProxy;
|
|
import com.sinosoft.utility.CError;
|
|
import com.sinosoft.utility.CErrors;
|
|
import com.sinosoft.utility.DBConnPool;
|
|
import com.sinosoft.utility.StrTool;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import java.sql.Connection;
|
|
import java.util.ArrayList;
|
|
import java.util.Vector;
|
|
|
|
/**
|
|
* <p>
|
|
* Title:公共加锁程序
|
|
* </p>
|
|
* <p>
|
|
* Description: 防止不同的业务岗位对同一笔业务做互斥的操作,如对与一个投保单,签单和删除动作为互斥的,当该投保单签单的时候就不能做删除
|
|
* </p>
|
|
* <p>
|
|
* Copyright: Copyright (c) 2007
|
|
* </p>
|
|
* <p>
|
|
* Company: SinoSoft
|
|
* </p>
|
|
*
|
|
* @author Fuqx
|
|
* @version 1.0
|
|
*/
|
|
|
|
public class PubLock {
|
|
LockAppSQL lockAppSQL = SQLProxy.getInstance(LockAppSQL.class);
|
|
private static final Logger logger = LoggerFactory.getLogger(PubLock.class);
|
|
public CErrors mErrors = new CErrors(); // 错误信息
|
|
private Connection con;
|
|
private ArrayList<String> mLockedNos = new ArrayList(); // 同一PubLock对象已经锁定的号码
|
|
/**
|
|
* mflag = true: 传入Connection mflag = false: 不传入Connection
|
|
*/
|
|
private boolean mflag = false;
|
|
private String mReason = "锁定应用模块不明确!";
|
|
|
|
public PubLock() {
|
|
}
|
|
|
|
public PubLock(Connection tConnection) {
|
|
con = tConnection;
|
|
mflag = true;
|
|
}
|
|
|
|
public boolean pareLockData(Connection conn, String tOperatedNo,
|
|
String tReason) {
|
|
try {
|
|
LockAppSchema tLockAppSchema = new LockAppSchema();
|
|
LockAppSet tLockAppSet = new LockAppSet();
|
|
LockAppDB tLockAppDB = new LockAppDB(conn);
|
|
tLockAppDB.setOperatedNo(tOperatedNo);
|
|
// 如果不存在任何应用模块对该记录加锁,则直接插入加锁信息
|
|
if (!tLockAppDB.getInfo()) {
|
|
tLockAppSchema.setOperatedNo(tOperatedNo);
|
|
tLockAppSchema.setState("1");
|
|
tLockAppSchema
|
|
.setReason(StrTool.cTrim(tReason).equals("") ? mReason
|
|
: tReason); // 当输入的原因为空时,取默认原因
|
|
tLockAppSchema.setMakeDate(PubFun.getCurrentDate());
|
|
tLockAppSchema.setMakeTime(PubFun.getCurrentTime());
|
|
tLockAppSchema.setModifyDate(PubFun.getCurrentDate());
|
|
tLockAppSchema.setModifyTime(PubFun.getCurrentTime());
|
|
tLockAppDB.setSchema(tLockAppSchema);
|
|
if (!tLockAppDB.insert()) {
|
|
this.mErrors.copyAllErrors(tLockAppDB.mErrors);
|
|
CError tError = new CError();
|
|
tError.moduleName = "PubLock";
|
|
tError.functionName = "pareLockData";
|
|
tError.errorMessage(new I18nMessage("表LockApp插库失败!", "LIS-11175"));
|
|
this.mErrors.addOneError(tError);
|
|
conn.rollback();
|
|
conn.close();
|
|
return false;
|
|
}
|
|
} else {
|
|
tLockAppDB = new LockAppDB(conn);
|
|
tLockAppSet = lockAppSQL.findAllByOperatedNoForUpdate(tOperatedNo);
|
|
if (tLockAppSet == null || tLockAppSet.size() == 0) {
|
|
CError tError = new CError();
|
|
tError.moduleName = "PubLock";
|
|
tError.functionName = "pareLockData";
|
|
tError.errorMessage(new I18nMessage("操作号:{0}对表LockApp中记录加锁失败!", "LIS-11176" , tOperatedNo));
|
|
this.mErrors.addOneError(tError);
|
|
conn.rollback();
|
|
conn.close();
|
|
return false;
|
|
}
|
|
tLockAppSchema = tLockAppSet.get(1);
|
|
if (!tLockAppSchema.getState().equals("0")) {
|
|
CError tError = new CError();
|
|
tError.moduleName = "PubLock";
|
|
tError.functionName = "pareLockData";
|
|
tError.errorMessage(new I18nMessage("操作号:{0}已经被其他业务锁定:{1}!", "LIS-11177" , tOperatedNo, tLockAppSchema.getReason()));
|
|
this.mErrors.addOneError(tError);
|
|
conn.rollback();
|
|
conn.close();
|
|
return false;
|
|
}
|
|
tLockAppSchema.setState("1");
|
|
tLockAppSchema.setMakeDate(PubFun.getCurrentDate());
|
|
tLockAppSchema.setMakeTime(PubFun.getCurrentTime());
|
|
tLockAppSchema.setModifyDate(PubFun.getCurrentDate());
|
|
tLockAppSchema.setModifyTime(PubFun.getCurrentTime());
|
|
tLockAppSchema.setReason(StrTool.cTrim(tReason).equals("") ? mReason : tReason);
|
|
tLockAppDB.setSchema(tLockAppSchema);
|
|
if (!tLockAppDB.update()) {
|
|
this.mErrors.copyAllErrors(tLockAppDB.mErrors);
|
|
CError tError = new CError();
|
|
tError.moduleName = "PubLock";
|
|
tError.functionName = "pareLockData";
|
|
tError.errorMessage(new I18nMessage("表LockApp更新失败!", "LIS-11178"));
|
|
this.mErrors.addOneError(tError);
|
|
conn.rollback();
|
|
conn.close();
|
|
return false;
|
|
}
|
|
}
|
|
} catch (Exception ex) {
|
|
CError tError = new CError();
|
|
tError.moduleName = "PubLock";
|
|
tError.functionName = "pareLockData";
|
|
tError.errorMessage(new I18nMessage( ex.toString(), null));
|
|
this.mErrors.addOneError(tError);
|
|
try {
|
|
conn.rollback();
|
|
conn.close();
|
|
} catch (Exception e) {
|
|
}
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public boolean pareUnLockData(Connection conn, String tOperatedNo) {
|
|
try {
|
|
LockAppSchema tLockAppSchema = new LockAppSchema();
|
|
LockAppSet tLockAppSet = new LockAppSet();
|
|
LockAppDB tLockAppDB = new LockAppDB(conn);
|
|
tLockAppDB.setOperatedNo(tOperatedNo);
|
|
// 如果原来没有加锁信息,直接返回
|
|
if (!tLockAppDB.getInfo()) {
|
|
return true;
|
|
} else {
|
|
//mysql 不支持nowait 暂时取消 nowait
|
|
tLockAppDB = new LockAppDB(conn);
|
|
tLockAppSet = lockAppSQL.findAllByOperatedNoForUpdate(tOperatedNo);
|
|
if (tLockAppSet == null || tLockAppSet.size() == 0) {
|
|
String aa = tLockAppDB.mErrors.getFirstError();
|
|
CError tError = new CError();
|
|
tError.moduleName = "PubLock";
|
|
tError.functionName = "pareUnLockData";
|
|
tError.errorMessage(new I18nMessage("操作号:{0}对表LockApp加锁失败!", "LIS-11179" , tOperatedNo));
|
|
this.mErrors.addOneError(tError);
|
|
conn.rollback();
|
|
conn.close();
|
|
return false;
|
|
}
|
|
tLockAppSchema = tLockAppSet.get(1);
|
|
if (tLockAppSchema.getState().equals("1")) {
|
|
tLockAppSchema.setState("0");
|
|
tLockAppSchema.setModifyDate(PubFun.getCurrentDate());
|
|
tLockAppSchema.setModifyTime(PubFun.getCurrentTime());
|
|
tLockAppDB.setSchema(tLockAppSchema);
|
|
if (!tLockAppDB.update()) {
|
|
this.mErrors.copyAllErrors(tLockAppDB.mErrors);
|
|
CError tError = new CError();
|
|
tError.moduleName = "PubLock";
|
|
tError.functionName = "pareUnLockData";
|
|
tError.errorMessage(new I18nMessage("表LockApp更新失败!", "LIS-11178"));
|
|
this.mErrors.addOneError(tError);
|
|
conn.rollback();
|
|
conn.close();
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
} catch (Exception ex) {
|
|
CError tError = new CError();
|
|
tError.moduleName = "PubLock";
|
|
tError.functionName = "pareLockData";
|
|
tError.errorMessage(new I18nMessage( ex.toString(), null));
|
|
this.mErrors.addOneError(tError);
|
|
try {
|
|
conn.rollback();
|
|
conn.close();
|
|
} catch (Exception e) {
|
|
}
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 对号码为tOperatedNo(如投保单号)的业务锁定,在解锁之前,除锁定业务外,其他业务不能对该号码做操作
|
|
*
|
|
* @parameter tOperatedNo 需要锁定的号码
|
|
* @parameter tReason 加锁理由
|
|
* @return 如果加锁成功,返回true;加锁失败,则返回false
|
|
*/
|
|
public boolean lock(String tOperatedNo, String tReason) {
|
|
try {
|
|
if (mLockedNos.contains(tOperatedNo)) {
|
|
logger.debug("本批次已经对号码成功锁定:" + tOperatedNo);
|
|
return true;
|
|
}
|
|
|
|
if (mflag == false) {
|
|
con = DBConnPool.getConnection();
|
|
}
|
|
if (con == null) {
|
|
// @@错误处理
|
|
CError tError = new CError();
|
|
tError.moduleName = "PubLock";
|
|
tError.functionName = "lock";
|
|
tError.errorMessage(new I18nMessage("数据库连接失败!", "LIS-06519"));
|
|
this.mErrors.addOneError(tError);
|
|
return false;
|
|
}
|
|
// 设置为非自动提交
|
|
con.setAutoCommit(false);
|
|
if (!pareLockData(con, tOperatedNo, tReason))
|
|
return false;
|
|
if (mflag == false) {
|
|
con.commit();
|
|
con.close();
|
|
mLockedNos.add(tOperatedNo); // 将锁定号码加入到集合中
|
|
}
|
|
|
|
} catch (Exception ex) {
|
|
CError tError = new CError();
|
|
tError.moduleName = "PubLock";
|
|
tError.functionName = "lock";
|
|
tError.errorMessage(new I18nMessage( ex.toString(), null));
|
|
this.mErrors.addOneError(tError);
|
|
try {
|
|
// 如果发生异常以后,关闭连接
|
|
if (mflag == false && !con.isClosed()) {
|
|
con.rollback();
|
|
con.close();
|
|
}
|
|
} catch (Exception e) {
|
|
}
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 对数组中tArrayNo包含的每一个tOperatedNo号码(如投保单号)的业务锁定,在解锁之前,除锁定业务外,其他业务不能对该号码组做操作
|
|
*
|
|
* @parameter tOperatedNo 需要锁定的号码
|
|
* @parameter tReason 加锁理由
|
|
* @return 如果所有的号码都加锁成功,返回true;如果其中一个加锁失败,则返回false
|
|
*/
|
|
public boolean lock(String[] tArrayNo, String tReason) {
|
|
try {
|
|
if (mflag == false) {
|
|
con = DBConnPool.getConnection();
|
|
}
|
|
if (con == null) {
|
|
// @@错误处理
|
|
CError tError = new CError();
|
|
tError.moduleName = "PubLock";
|
|
tError.functionName = "lock";
|
|
tError.errorMessage(new I18nMessage("数据库连接失败!", "LIS-06519"));
|
|
this.mErrors.addOneError(tError);
|
|
return false;
|
|
}
|
|
// 设置为非自动提交
|
|
con.setAutoCommit(false);
|
|
for (int i = 0; i < tArrayNo.length; i++) {
|
|
if (mLockedNos.contains(tArrayNo[i])) {
|
|
logger.debug("本批次已经对号码成功锁定:" + tArrayNo[i]);
|
|
continue;
|
|
}
|
|
if (!pareLockData(con, tArrayNo[i], tReason))
|
|
return false;
|
|
|
|
}
|
|
if (mflag == false) {
|
|
con.commit();
|
|
con.close();
|
|
// 对非传如连接的,保存该批次传入需要锁定
|
|
for (int j = 0; j < tArrayNo.length; j++) {
|
|
if (!mLockedNos.contains(tArrayNo[j])) // 如果号码中不包含这个号,加入集合中
|
|
{
|
|
mLockedNos.add(tArrayNo[j]);
|
|
}
|
|
}
|
|
}
|
|
} catch (Exception ex) {
|
|
CError tError = new CError();
|
|
tError.moduleName = "PubLock";
|
|
tError.functionName = "lock";
|
|
tError.errorMessage(new I18nMessage( ex.toString(), null));
|
|
this.mErrors.addOneError(tError);
|
|
try {
|
|
// 如果发生异常以后,关闭连接
|
|
if (mflag == false && !con.isClosed()) {
|
|
con.rollback();
|
|
con.close();
|
|
}
|
|
} catch (Exception e) {
|
|
}
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 对号码为tOperatedNo(如投保单号)的业务解除锁定,解锁后,允许其他业务对该号码对应的记录做操作
|
|
*
|
|
* @parameter tOperatedNo 需要解锁的号码
|
|
* @return 如果解锁成功,返回true;解锁失败,则返回false
|
|
*/
|
|
public boolean unLock(String tOperatedNo) {
|
|
try {
|
|
if (mflag == false) {
|
|
con = DBConnPool.getConnection();
|
|
}
|
|
if (con == null) {
|
|
// @@错误处理
|
|
CError tError = new CError();
|
|
tError.moduleName = "PubLock";
|
|
tError.functionName = "unLock";
|
|
tError.errorMessage(new I18nMessage("数据库连接失败!", "LIS-06519"));
|
|
this.mErrors.addOneError(tError);
|
|
return false;
|
|
}
|
|
// 设置为非自动提交
|
|
con.setAutoCommit(false);
|
|
// 解锁数据准备
|
|
if (!pareUnLockData(con, tOperatedNo))
|
|
return false;
|
|
if (mflag == false) {
|
|
con.commit();
|
|
con.close();
|
|
// 当解锁成功,删除集合中的号码
|
|
if (mLockedNos.contains(tOperatedNo)) {
|
|
mLockedNos.remove(tOperatedNo);
|
|
}
|
|
}
|
|
|
|
} catch (Exception ex) {
|
|
CError tError = new CError();
|
|
tError.moduleName = "PubLock";
|
|
tError.functionName = "lock";
|
|
tError.errorMessage(new I18nMessage( ex.toString(), null));
|
|
this.mErrors.addOneError(tError);
|
|
try {
|
|
// 如果发生异常以后,关闭连接
|
|
if (mflag == false && !con.isClosed()) {
|
|
con.rollback();
|
|
con.close();
|
|
}
|
|
} catch (Exception e) {
|
|
}
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
public boolean unLock(String[] tArrayNo) {
|
|
|
|
try {
|
|
if (mflag == false) {
|
|
con = DBConnPool.getConnection();
|
|
}
|
|
if (con == null) {
|
|
// @@错误处理
|
|
CError tError = new CError();
|
|
tError.moduleName = "PubLock";
|
|
tError.functionName = "unLock";
|
|
tError.errorMessage(new I18nMessage("数据库连接失败!", "LIS-06519"));
|
|
this.mErrors.addOneError(tError);
|
|
return false;
|
|
}
|
|
|
|
// 设置为非自动提交
|
|
con.setAutoCommit(false);
|
|
// 解锁数据准备
|
|
for (int i = 0; i < tArrayNo.length; i++) {
|
|
if (!pareUnLockData(con, tArrayNo[i]))
|
|
return false;
|
|
}
|
|
if (mflag == false) {
|
|
con.commit();
|
|
con.close();
|
|
for (int j = 0; j < tArrayNo.length; j++) {
|
|
if (mLockedNos.contains(tArrayNo[j])) {
|
|
mLockedNos.remove(tArrayNo[j]);
|
|
}
|
|
}
|
|
}
|
|
} catch (Exception ex) {
|
|
CError tError = new CError();
|
|
tError.moduleName = "PubLock";
|
|
tError.functionName = "lock";
|
|
tError.errorMessage(new I18nMessage( ex.toString(), null));
|
|
this.mErrors.addOneError(tError);
|
|
try {
|
|
// 如果发生异常以后,关闭连接
|
|
if (mflag == false && !con.isClosed()) {
|
|
con.rollback();
|
|
con.close();
|
|
}
|
|
} catch (Exception e) {
|
|
}
|
|
return false;
|
|
}
|
|
return true;
|
|
|
|
}
|
|
}
|
|
|