Index: ssts-web/src/main/resources/spring/applicationContext-disinfectsystem-service.xml =================================================================== diff -u -r16120 -r16492 --- ssts-web/src/main/resources/spring/applicationContext-disinfectsystem-service.xml (.../applicationContext-disinfectsystem-service.xml) (revision 16120) +++ ssts-web/src/main/resources/spring/applicationContext-disinfectsystem-service.xml (.../applicationContext-disinfectsystem-service.xml) (revision 16492) @@ -1861,12 +1861,28 @@ PROPAGATION_REQUIRED + PROPAGATION_REQUIRES_NEW + + + + + + + + PROPAGATION_REQUIRED + PROPAGATION_REQUIRES_NEW + + + + + + Index: ssts-web/src/main/java/com/forgon/disinfectsystem/initdata/service/InitializeDataManagerImpl.java =================================================================== diff -u -r16489 -r16492 --- ssts-web/src/main/java/com/forgon/disinfectsystem/initdata/service/InitializeDataManagerImpl.java (.../InitializeDataManagerImpl.java) (revision 16489) +++ ssts-web/src/main/java/com/forgon/disinfectsystem/initdata/service/InitializeDataManagerImpl.java (.../InitializeDataManagerImpl.java) (revision 16492) @@ -64,7 +64,7 @@ import com.forgon.security.service.RoleManager; import com.forgon.serialnumber.model.SerialNum; import com.forgon.serialnumber.service.SerialNumManager; -import com.forgon.serialnumber.service.SerialNumManagerImpl; +import com.forgon.serialnumber.service.SerialNumUpdateManager; import com.forgon.systemsetting.model.HttpOption; import com.forgon.systemsetting.service.HttpOptionManager; import com.forgon.tools.db.InitDbConnection; @@ -280,7 +280,7 @@ } serialNumManager.initSerialNumInMemory(serialNum); int currrentSerialNum = Integer.parseInt(serialNumber); - serialNum.setSerialNumber("" + (currrentSerialNum + SerialNumManagerImpl.PREFENTCH_SIZE)); + serialNum.setSerialNumber("" + (currrentSerialNum + SerialNumUpdateManager.PREFENTCH_SIZE)); objectDao.saveOrUpdate(serialNum); } } Index: forgon-core/src/main/java/com/forgon/serialnumber/service/SerialNumUpdateManagerImpl.java =================================================================== diff -u --- forgon-core/src/main/java/com/forgon/serialnumber/service/SerialNumUpdateManagerImpl.java (revision 0) +++ forgon-core/src/main/java/com/forgon/serialnumber/service/SerialNumUpdateManagerImpl.java (revision 16492) @@ -0,0 +1,69 @@ +package com.forgon.serialnumber.service; + +import org.apache.commons.lang.StringUtils; + +import com.forgon.serialnumber.model.SerialNum; +import com.forgon.serialnumber.model.SerialNumVo; +import com.forgon.tools.hibernate.BasePoManagerImpl; + +public class SerialNumUpdateManagerImpl extends BasePoManagerImpl implements SerialNumUpdateManager { + + + public SerialNumUpdateManagerImpl() { + super(SerialNum.class); + } + + @Override + public void updateSerialNumVo_TRANS_NEW(String type, SerialNumVo vo) { + + if(vo == null){ + return; + } + SerialNum serialNumObj = getSerialNumberWithUpdateLock(type,true); + if(serialNumObj != null){ + String serialNumStr = serialNumObj.getSerialNumber(); + if(StringUtils.isBlank(serialNumStr)){ + serialNumStr = SERIAL_NUMBER_START + ""; + } + int num = Integer.parseInt(serialNumStr); + serialNumObj.setSerialNumber("" + (num + PREFENTCH_SIZE)); + objectDao.saveOrUpdate(serialNumObj); + objectDao.flush(); + vo.setSerialNum(num); + vo.setCount(PREFENTCH_SIZE); + } + + } + /** + * 获取序列号对象并根据参数是否锁表,如果锁表,查询和更新都会锁表 + * @param type + * @param withUpdateLock + * @return + */ + private SerialNum getSerialNumberWithUpdateLock(String type, Boolean withUpdateLock) { + + SerialNum serialNum = null; + + if (StringUtils.isNotBlank(type)) { + + String sql = "where po.type = '" + type + "'"; + + Object object = null; + if(withUpdateLock){ + object = objectDao.getBySql_ForUpdate(poName, sql); + }else{ + object = objectDao.getBySql(poName, sql); + } + + if(object != null && object instanceof SerialNum){ + serialNum = (SerialNum)object; + } + } + return serialNum; + } + + @Override + public SerialNum getSerialNumberWithoutLock(String type) { + return getSerialNumberWithUpdateLock(type,false); + } +} Index: forgon-core/src/main/java/com/forgon/serialnumber/service/SerialNumManagerImpl.java =================================================================== diff -u -r16490 -r16492 --- forgon-core/src/main/java/com/forgon/serialnumber/service/SerialNumManagerImpl.java (.../SerialNumManagerImpl.java) (revision 16490) +++ forgon-core/src/main/java/com/forgon/serialnumber/service/SerialNumManagerImpl.java (.../SerialNumManagerImpl.java) (revision 16492) @@ -24,15 +24,14 @@ private ObjectDao objectDao; private SerialNumberDao serialNumberDao; + private SerialNumUpdateManager serialNumUpdateManager; private static SerialNumVo barcodeSerialNum = null; private static SerialNumVo applicationSerialNum = null; private static SerialNumVo godownSerialNum = null; private static SerialNumVo invoiceSerialNum = null; private static SerialNumVo cleanSerialNum = null; - public static final int PREFENTCH_SIZE = 1000; - private static final int SERIAL_NUMBER_START = 1; private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd"); public void setSerialNumberDao(SerialNumberDao serialNumberDao) { @@ -48,45 +47,17 @@ objectDao.saveOrUpdate(serialNum); } + public void setSerialNumUpdateManager( + SerialNumUpdateManager serialNumUpdateManager) { + this.serialNumUpdateManager = serialNumUpdateManager; + } + @Override public SerialNum getSerialNumber(String type) { - - return getSerialNumberWithUpdateLock(type, false); + return serialNumUpdateManager.getSerialNumberWithoutLock(type); } - private SerialNum getSerialNumberWithUpdateLock(String type, Boolean withUpdateLock) { - - SerialNum serialNum = null; - - if (StringUtils.isNotBlank(type)) { - - String sql = "where po.type = '" + type + "'"; - - Object object = null; - if(withUpdateLock){ - object = objectDao.getBySql_ForUpdate(SerialNum.class.getSimpleName(), sql); - }else{ - object = objectDao.getBySql(SerialNum.class.getSimpleName(), sql); - } - - if(object != null && object instanceof SerialNum){ - serialNum = (SerialNum)object; - } - //Query query = objectDao.getHibernateSession().createQuery(sql); - -// if (withUpdateLock){ -// query.setLockMode("sn",LockMode.FORCE); // 加锁 -// } -// -// List list = query.list();// 执行查询,获取数据 -// if (list != null && list.size() >= 1) { -// serialNum = (SerialNum) list.get(0); -// } - } - return serialNum; - } - private SerialNumVo getSerialNumVoByType(String type){ if(SerialNum.TYPE_RECYCLINGAPPLICATION.equals(type)){ return applicationSerialNum; @@ -126,13 +97,13 @@ SerialNumVo vo = getSerialNumVoByType(type); if(vo == null){ vo = new SerialNumVo(); - vo.setCount(PREFENTCH_SIZE); + vo.setCount(SerialNumUpdateManager.PREFENTCH_SIZE); String serialNumberStr = serialNum.getSerialNumber(); if (StringUtils.isNotBlank(serialNumberStr) && StringUtils.isNumeric(serialNumberStr)) { vo.setSerialNum(Integer.parseInt(serialNumberStr)); } else { - vo.setSerialNum(SERIAL_NUMBER_START); + vo.setSerialNum(SerialNumUpdateManager.SERIAL_NUMBER_START); } vo.setSnMode(serialNum.getDefaultSerialNum()); vo.setIsEveryDayClean(serialNum.getIsEveryDayClean()); @@ -153,10 +124,10 @@ if (!currentDate.equals(vo .getDateTime())) { vo.setDateTime(currentDate); - vo.setCount(PREFENTCH_SIZE); - vo.setSerialNum(SERIAL_NUMBER_START); + vo.setCount(SerialNumUpdateManager.PREFENTCH_SIZE); + vo.setSerialNum(SerialNumUpdateManager.SERIAL_NUMBER_START); SerialNum serialNumObj = getSerialNumber(type); - serialNumObj.setSerialNumber((SERIAL_NUMBER_START + PREFENTCH_SIZE)+""); + serialNumObj.setSerialNumber((SerialNumUpdateManager.SERIAL_NUMBER_START + SerialNumUpdateManager.PREFENTCH_SIZE)+""); serialNumObj.setDateTime(currentDate); objectDao.saveOrUpdate(serialNumObj); } @@ -189,31 +160,19 @@ isEveryDayClean(vo,currentDate,type); //每1000条流水号更新一次数据库 if(vo.getCount() == 0){ - SerialNum serialNumObj = getSerialNumberWithUpdateLock(type,true); - if(serialNumObj != null){ - String serialNumStr = serialNumObj.getSerialNumber(); - if(StringUtils.isBlank(serialNumStr)){ - serialNumStr = SERIAL_NUMBER_START + ""; - } - int num = Integer.parseInt(serialNumStr); - serialNumObj.setSerialNumber("" + (num + PREFENTCH_SIZE)); - objectDao.saveOrUpdate(serialNumObj); - objectDao.flush(); - vo.setSerialNum(num); - vo.setCount(PREFENTCH_SIZE); - } + serialNumUpdateManager.updateSerialNumVo_TRANS_NEW(type, vo); } //验证流水号是否未初始化 if(vo.getSerialNum() < 0){ SerialNum serialNumObj = getSerialNumber(type); if(serialNumObj != null){ String numStr = serialNumObj.getSerialNumber(); if(StringUtils.isBlank(numStr)){ - numStr = SERIAL_NUMBER_START + ""; + numStr = SerialNumUpdateManager.SERIAL_NUMBER_START + ""; } initSerialNumInMemory(serialNumObj); }else{ - vo.setSerialNum(SERIAL_NUMBER_START); + vo.setSerialNum(SerialNumUpdateManager.SERIAL_NUMBER_START); } } Integer serialNum = vo.getSerialNum(); Index: forgon-core/src/main/java/com/forgon/serialnumber/service/SerialNumUpdateManager.java =================================================================== diff -u --- forgon-core/src/main/java/com/forgon/serialnumber/service/SerialNumUpdateManager.java (revision 0) +++ forgon-core/src/main/java/com/forgon/serialnumber/service/SerialNumUpdateManager.java (revision 16492) @@ -0,0 +1,27 @@ +package com.forgon.serialnumber.service; + +import com.forgon.serialnumber.model.SerialNum; +import com.forgon.serialnumber.model.SerialNumVo; +import com.forgon.tools.hibernate.BasePoManager; + +/** + * 从数据库更新序列号的Vo缓存。需要在新的事务中读取数据库,读取完数据库就释放锁。读和写都会锁表 + * @author kzh + * + */ +public interface SerialNumUpdateManager extends BasePoManager { + public static final int PREFENTCH_SIZE = 1000; + public static final int SERIAL_NUMBER_START = 1; + /** + * 在新的事务中更新序列号缓存。需要在线程互斥的环境下执行。如果多线程同时访问,会有死锁的可能 + * @param type + * @param vo + */ + public void updateSerialNumVo_TRANS_NEW(String type, SerialNumVo vo); + /** + * 从数据库中获取序列号对象,不锁表,只做查询。所以返回结果可能会是脏数据 + * @param type + * @return + */ + public SerialNum getSerialNumberWithoutLock(String type); +}