- 浏览: 53448 次
- 性别:
- 来自: 香港
文章分类
最新评论
-
夜游神:
看完此文身有感处,每次写代码都是copy来copy去,程序员快 ...
自动编码的探讨与实现 -
chen4059:
双机冷备,HA吧。
想好就要投入啊。
赛的VCS不错。
连接池控制多个数据源 -
jayxu:
你的应用场景没必要这样做
连接池控制多个数据源 -
whitesock:
使用LVS
连接池控制多个数据源 -
taojingrui:
Weblogic 有multiple datasource 的 ...
连接池控制多个数据源
项目在压力测试中有个业务流程无法通过50个用户同时并发,初步认为是由于一个实体类无法和数据库同步而失败。这个实体类是下面错误信息中的SysBillManage。
首先简单的说明一下SysBillManage,它的功能是根据传递参数分配单据号,并且实现自增。比如是出库通知单,那么参数是OUT_DO_INFORM_ORDER,那么得到的结果是OutB0000001这样的形式的单据号,每一次增加出库通知单则单据号增1,既是OutB0000002。其中参数OUT_DO_INFORM_ORDER对应于数据库SysBillManage表中的一条记录的ID。
在用silkperformer 6.5做压力测试的时候,则出现一下异常,测试用例就是并发生成出库通知单:
看到这个错误,就想到可能是代码没有同步,但是事实上代码已经做了简单的同步。
在SysBillManageServiceImpl中,既是service的实现代码,其中getOrderNO(String billsort)是获得单据号的方法。
在SysBillManageDAO中的代码:
请各位大大看看到底是哪里出了问题
请问为什么INT类型的PK比STRING类型引发的死锁要少呢?
page lock?不是很清楚引发它的原因!你可以不可以说得再仔细点呢?学习一下^^
换数据库是不能了,数据库和测试数据是检测中心给定的,现今就没办法改动了.因为时间也很紧张!
换jtds驱动包和改成int类pk,这个稍后去试试...待会看下结果.一直都知道string类型慢,但是引起并发lock那么严重就不知道了...经验尚浅
首先简单的说明一下SysBillManage,它的功能是根据传递参数分配单据号,并且实现自增。比如是出库通知单,那么参数是OUT_DO_INFORM_ORDER,那么得到的结果是OutB0000001这样的形式的单据号,每一次增加出库通知单则单据号增1,既是OutB0000002。其中参数OUT_DO_INFORM_ORDER对应于数据库SysBillManage表中的一条记录的ID。
在用silkperformer 6.5做压力测试的时候,则出现一下异常,测试用例就是并发生成出库通知单:
11:06:10,609 ERROR JDBCExceptionReporter:72 - [Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]事务(进程 ID 98)与另一个进程已被死锁在 lock 资源上,且该事务已被选作死锁牺牲品。请重新运行该事务。 11:06:10,609 ERROR AbstractFlushingEventListener:299 - Could not synchronize database state with session org.hibernate.exception.GenericJDBCException: could not update: [com.bnu.put.base.billmanage.model.SysBillManage#OUT_DO_INFORM_ORDER] at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:91) at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:79) at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43) at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2222) at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2118) at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2374) at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:84) at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:243) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:227) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141) at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:296) at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27) at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1009) at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:356) at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106) at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:584) at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:500) at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:473) at org.springframework.transaction.interceptor.TransactionAspectSupport.doCommitTransactionAfterReturning(TransactionAspectSupport.java:266) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176) at $Proxy23.auditCoConsignOrder(Unknown Source) at com.bnu.put.order.consign.view.action.OutConsignOrderAction.audit(OutConsignOrderAction.java:280) at sun.reflect.GeneratedMethodAccessor374.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:276) at org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:196) at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:421) at net.sf.struts.saif.SAIFTilesRequestProcessor.processActionPerform(SAIFTilesRequestProcessor.java:91) at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:226) at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1158) at com.bnu.put.view.util.stationListener.process(stationListener.java:52) at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:397) at javax.servlet.http.HttpServlet.service(HttpServlet.java:689) at javax.servlet.http.HttpServlet.service(HttpServlet.java:802) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:174) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:75) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:292) at org.acegisecurity.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116) at org.acegisecurity.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:79) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:303) at org.acegisecurity.ui.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:143) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:303) at org.acegisecurity.ui.switchuser.SwitchUserProcessingFilter.doFilter(SwitchUserProcessingFilter.java:382) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:303) at org.acegisecurity.providers.anonymous.AnonymousProcessingFilter.doFilter(AnonymousProcessingFilter.java:138) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:303) at org.acegisecurity.ui.rememberme.RememberMeProcessingFilter.doFilter(RememberMeProcessingFilter.java:174) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:303) at org.acegisecurity.ui.basicauth.BasicProcessingFilter.doFilter(BasicProcessingFilter.java:214) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:303) at org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:246) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:303) at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:220) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:303) at org.acegisecurity.util.FilterChainProxy.doFilter(FilterChainProxy.java:173) at org.acegisecurity.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:120) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:744) at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527) at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80) at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684) at java.lang.Thread.run(Unknown Source) Caused by: java.sql.SQLException: [Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]事务(进程 ID 98)与另一个进程已被死锁在 lock 资源上,且该事务已被选作死锁牺牲品。请重新运行该事务。 at com.microsoft.jdbc.base.BaseExceptions.createException(Unknown Source) at com.microsoft.jdbc.base.BaseExceptions.getException(Unknown Source) at com.microsoft.jdbc.sqlserver.tds.TDSRequest.processErrorToken(Unknown Source) at com.microsoft.jdbc.sqlserver.tds.TDSRequest.processReplyToken(Unknown Source) at com.microsoft.jdbc.sqlserver.tds.TDSRPCRequest.processReplyToken(Unknown Source) at com.microsoft.jdbc.sqlserver.tds.TDSRequest.processReply(Unknown Source) at com.microsoft.jdbc.sqlserver.SQLServerImplStatement.getNextResultType(Unknown Source) at com.microsoft.jdbc.base.BaseStatement.commonTransitionToState(Unknown Source) at com.microsoft.jdbc.base.BaseStatement.postImplExecute(Unknown Source) at com.microsoft.jdbc.base.BasePreparedStatement.postImplExecute(Unknown Source) at com.microsoft.jdbc.base.BaseStatement.commonExecute(Unknown Source) at com.microsoft.jdbc.base.BaseStatement.executeUpdateInternal(Unknown Source) at com.microsoft.jdbc.base.BasePreparedStatement.executeUpdate(Unknown Source) at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:101) at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:23) at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2204) ... 77 more 11:06:10,625 WARN RequestProcessor:509 - Unhandled Exception thrown: class org.springframework.dao.DeadlockLoserDataAccessException 11:06:10,625 ERROR [action]:253 - Servlet.service() for servlet action threw exception org.springframework.dao.DeadlockLoserDataAccessException: Hibernate operation: could not update: [com.bnu.put.base.billmanage.model.SysBillManage#OUT_DO_INFORM_ORDER]; SQL [update dbo.SYS_BILL_MANAGE set TYPE_PREFIX=?, START_NUMBER=?, CODE_FORMAT=?, CURRENT_NUMBER=?, REMARK=? where BILL_TYPE=?]; [Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]事务(进程 ID 98)与另一个进程已被死锁在 lock 资源上,且该事务已被选作死锁牺牲品。请重新运行该事务。; nested exception is java.sql.SQLException: [Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]事务(进程 ID 98)与另一个进程已被死锁在 lock 资源上,且该事务已被选作死锁牺牲品。请重新运行该事务。 java.sql.SQLException: [Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]事务(进程 ID 98)与另一个进程已被死锁在 lock 资源上,且该事务已被选作死锁牺牲品。请重新运行该事务。 at com.microsoft.jdbc.base.BaseExceptions.createException(Unknown Source) at com.microsoft.jdbc.base.BaseExceptions.getException(Unknown Source) at com.microsoft.jdbc.sqlserver.tds.TDSRequest.processErrorToken(Unknown Source) at com.microsoft.jdbc.sqlserver.tds.TDSRequest.processReplyToken(Unknown Source) at com.microsoft.jdbc.sqlserver.tds.TDSRPCRequest.processReplyToken(Unknown Source) at com.microsoft.jdbc.sqlserver.tds.TDSRequest.processReply(Unknown Source) at com.microsoft.jdbc.sqlserver.SQLServerImplStatement.getNextResultType(Unknown Source) at com.microsoft.jdbc.base.BaseStatement.commonTransitionToState(Unknown Source) at com.microsoft.jdbc.base.BaseStatement.postImplExecute(Unknown Source) at com.microsoft.jdbc.base.BasePreparedStatement.postImplExecute(Unknown Source) at com.microsoft.jdbc.base.BaseStatement.commonExecute(Unknown Source) at com.microsoft.jdbc.base.BaseStatement.executeUpdateInternal(Unknown Source) at com.microsoft.jdbc.base.BasePreparedStatement.executeUpdate(Unknown Source) at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:101) at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:23) at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2204) at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2118) at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2374) at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:84) at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:243) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:227) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141) at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:296) at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27) at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1009) at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:356) at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106) at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:584) at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:500) at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:473) at org.springframework.transaction.interceptor.TransactionAspectSupport.doCommitTransactionAfterReturning(TransactionAspectSupport.java:266) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176) at $Proxy23.auditCoConsignOrder(Unknown Source) at com.bnu.put.order.consign.view.action.OutConsignOrderAction.audit(OutConsignOrderAction.java:280) at sun.reflect.GeneratedMethodAccessor374.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:276) at org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:196) at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:421) at net.sf.struts.saif.SAIFTilesRequestProcessor.processActionPerform(SAIFTilesRequestProcessor.java:91) at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:226) at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1158) at com.bnu.put.view.util.stationListener.process(stationListener.java:52) at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:397) at javax.servlet.http.HttpServlet.service(HttpServlet.java:689) at javax.servlet.http.HttpServlet.service(HttpServlet.java:802) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:174) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:75) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:292) at org.acegisecurity.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116) at org.acegisecurity.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:79) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:303) at org.acegisecurity.ui.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:143) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:303) at org.acegisecurity.ui.switchuser.SwitchUserProcessingFilter.doFilter(SwitchUserProcessingFilter.java:382) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:303) at org.acegisecurity.providers.anonymous.AnonymousProcessingFilter.doFilter(AnonymousProcessingFilter.java:138) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:303) at org.acegisecurity.ui.rememberme.RememberMeProcessingFilter.doFilter(RememberMeProcessingFilter.java:174) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:303) at org.acegisecurity.ui.basicauth.BasicProcessingFilter.doFilter(BasicProcessingFilter.java:214) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:303) at org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:246) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:303) at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:220) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:303) at org.acegisecurity.util.FilterChainProxy.doFilter(FilterChainProxy.java:173) at org.acegisecurity.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:120) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:744) at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527) at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80) at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684) at java.lang.Thread.run(Unknown Source)
看到这个错误,就想到可能是代码没有同步,但是事实上代码已经做了简单的同步。
在SysBillManageServiceImpl中,既是service的实现代码,其中getOrderNO(String billsort)是获得单据号的方法。
private SysBillManageDAO sysbillmanagedao; private SysBillManage sysbillmanage; //...其他处理 public synchronized String getOrderNO(String billsort) { if (sysbillmanagedao.findById(billsort) != null) { this.sysbillmanage = sysbillmanagedao.findById(billsort); int currentnumber = Integer.parseInt(sysbillmanage .getCurrentNumber()); currentnumber++; String factcurrentnumber = "" + currentnumber; String billtypeprefix = sysbillmanage.getTypePrefix(); String billcodeformat = sysbillmanage.getCodeFormat(); String factbillcodeformat = leftAppend(billcodeformat, factcurrentnumber); sysbillmanage.setCurrentNumber(factcurrentnumber); this.save(sysbillmanage); return billtypeprefix + factbillcodeformat; } else { sysbillmanage = new SysBillManage(); sysbillmanage.setBillType(billsort); sysbillmanage.setTypePrefix(this.getbillprefix(billsort)); sysbillmanage.setStartNumber("1"); sysbillmanage.setCurrentNumber("1"); sysbillmanage.setCodeFormat("0000000"); sysbillmanage.setRemark(""); this.save(sysbillmanage); String factcurrentnumber = sysbillmanage.getCurrentNumber(); String billcodeformat = sysbillmanage.getCodeFormat(); String factbillcodeformat = leftAppend(billcodeformat, factcurrentnumber); return this.getbillprefix(billsort) + factbillcodeformat; } }
public String getbillprefix(String billsort) { for (int i = 0; i < ordernoprix.length; i++) { if (billsort == ordernoprix[i][0]) { return ordernoprix[i][1]; } } return null; }
在SysBillManageDAO中的代码:
/** * Data access object (DAO) for domain model class SysBillManage. * @see model.SysBillManage * @author MyEclipse - Hibernate Tools */ public class SysBillManageDAO extends HibernateDaoSupport { private static final Log log = LogFactory.getLog(SysBillManageDAO.class); protected void initDao() { //do nothing } public void save(SysBillManage transientInstance) { log.debug("saving SysBillManage instance"); try { getHibernateTemplate().saveOrUpdate(transientInstance); System.out.println("OK"); log.debug("save successful"); } catch (RuntimeException re) { log.error("save failed", re); System.out.println("Error"); throw re; } } public void delete(SysBillManage persistentInstance) { log.debug("deleting SysBillManage instance"); try { getHibernateTemplate().delete(persistentInstance); log.debug("delete successful"); } catch (RuntimeException re) { log.error("delete failed", re); throw re; } } public SysBillManage findById( java.lang.String id) { log.debug("getting SysBillManage instance with id: " + id); try { SysBillManage instance = (SysBillManage) getHibernateTemplate() .get("com.bnu.put.base.billmanage.model.SysBillManage", id); // SysBillManage instance2 = (SysBillManage) getHibernateTemplate().load(SysBillManage.class,id); return instance; } catch (RuntimeException re) { log.error("get failed", re); throw re; } } public List findByExample(SysBillManage instance) { log.debug("finding SysBillManage instance by example"); try { List results = getSession() .createCriteria("model.SysBillManage") .add(Example.create(instance)) .list(); log.debug("find by example successful, result size: " + results.size()); return results; } catch (RuntimeException re) { log.error("find by example failed", re); throw re; } } public SysBillManage merge(SysBillManage detachedInstance) { log.debug("merging SysBillManage instance"); try { SysBillManage result = (SysBillManage) getHibernateTemplate() .merge(detachedInstance); log.debug("merge successful"); return result; } catch (RuntimeException re) { log.error("merge failed", re); throw re; } } public void attachDirty(SysBillManage instance) { log.debug("attaching dirty SysBillManage instance"); try { getHibernateTemplate().saveOrUpdate(instance); log.debug("attach successful"); } catch (RuntimeException re) { log.error("attach failed", re); throw re; } } public void attachClean(SysBillManage instance) { log.debug("attaching clean SysBillManage instance"); try { getHibernateTemplate().lock(instance, LockMode.NONE); log.debug("attach successful"); } catch (RuntimeException re) { log.error("attach failed", re); throw re; } } public void update(SysBillManage persistentInstance) { log.debug("deleting SysBillManage instance"); try { getHibernateTemplate().update(persistentInstance); log.debug("delete successful"); } catch (RuntimeException re) { log.error("delete failed", re); throw re; } } }
请各位大大看看到底是哪里出了问题
评论
10 楼
denghan
2007-03-31
50个用户同时并发
------------------
请教楼主用什么测试软件可以实现50个用户的并发访问?可以告诉个软件名称吗?
非常感谢~!
------------------
请教楼主用什么测试软件可以实现50个用户的并发访问?可以告诉个软件名称吗?
非常感谢~!
9 楼
lzzzl
2007-02-09
Readonly 写道
string类型PK改到数字类型PK只能减少page lock,但是不能消除。
根本的解决方法是改序列号生成方法,像你这种在一个表里面记录最大值,然后不停累加,然后再更新到其他表,很容易出deadlock。
你可以将这个最大值在系统启动的时候从各个表读取,然后更新,并且把这个值放到内存中,这样在系统运行中的时候就不需要和这个表打交道了。
这里有一些其他技巧减少lock的资料,也可以参考一下:
http://www.sql-server-performance.com/reducing_locks.asp
根本的解决方法是改序列号生成方法,像你这种在一个表里面记录最大值,然后不停累加,然后再更新到其他表,很容易出deadlock。
你可以将这个最大值在系统启动的时候从各个表读取,然后更新,并且把这个值放到内存中,这样在系统运行中的时候就不需要和这个表打交道了。
这里有一些其他技巧减少lock的资料,也可以参考一下:
http://www.sql-server-performance.com/reducing_locks.asp
请问为什么INT类型的PK比STRING类型引发的死锁要少呢?
8 楼
pedestrian_I
2006-10-08
问题解决了,现在可以支持100个用户并发了,操作流程比较多,数据量为8W条单据。只在Dao层update方法中加多了一行代码getHibernateTemplate().flush();马上就写入数据库,就不会出现不同步和记录重复的情况了。花了好久才试出这个解决方法。
并发情况下,首先是某用户A取得单据号001,然后将sysBillMange update,执行getHibernateTemplate().update(persistentInstance);这个方法。此时getOrderNO这个方法结束,同步完成,下一个用户B进入方法,执行get取得单据号的操作,但是这个时候,用户A的update动作还未真正写入数据库,此时用户B取得的还是001而不是002。所以就出错了,所以我尝试着将它立即写入数据库,系统压力测试就正常了。
其他代码都没有在执行动作之后立即flush,系统瓶颈在这里,所有操作都要涉及到这个表,虽然这种写法比较慢……
spring的配置应该保证了事务的原子性,但是还是出现这样的事务问题,到底是为什么呢?难道是粒度问题?
事务A开始
{
事务B...
}事务A结束
难道是保证了事务A而在事务A中的事务B(既是这里的取得更新单据号)没有保证?
象你这个需求,从实现方式上面就已经形成了一个瓶颈,所有的操作都集中在一个表上,要在上面取ID,并发的时候出现deadlock或者取出同一个id就是必然了,建议采用缓冲的机制,对于每个用户,他每次到ID表中取的ID的时候,都是取回一批ID,另外一个session来取得时候,拿到的是另外一批,然后这个用户在生成ID的时候,从这个缓冲中取,取尽的时候才重新去表中得到另外一批ID。
缓存是一个很好的方案,hibernate的缓存机制还没用上,找个时间研究下。^^
public void update(SysBillManage persistentInstance) { log.debug("deleting SysBillManage instance"); try { getHibernateTemplate().update(persistentInstance); getHibernateTemplate().flush(); log.debug("delete successful"); } catch (RuntimeException re) { log.error("delete failed", re); throw re; } }
并发情况下,首先是某用户A取得单据号001,然后将sysBillMange update,执行getHibernateTemplate().update(persistentInstance);这个方法。此时getOrderNO这个方法结束,同步完成,下一个用户B进入方法,执行get取得单据号的操作,但是这个时候,用户A的update动作还未真正写入数据库,此时用户B取得的还是001而不是002。所以就出错了,所以我尝试着将它立即写入数据库,系统压力测试就正常了。
其他代码都没有在执行动作之后立即flush,系统瓶颈在这里,所有操作都要涉及到这个表,虽然这种写法比较慢……
spring的配置应该保证了事务的原子性,但是还是出现这样的事务问题,到底是为什么呢?难道是粒度问题?
事务A开始
{
事务B...
}事务A结束
难道是保证了事务A而在事务A中的事务B(既是这里的取得更新单据号)没有保证?
引用
象你这个需求,从实现方式上面就已经形成了一个瓶颈,所有的操作都集中在一个表上,要在上面取ID,并发的时候出现deadlock或者取出同一个id就是必然了,建议采用缓冲的机制,对于每个用户,他每次到ID表中取的ID的时候,都是取回一批ID,另外一个session来取得时候,拿到的是另外一批,然后这个用户在生成ID的时候,从这个缓冲中取,取尽的时候才重新去表中得到另外一批ID。
缓存是一个很好的方案,hibernate的缓存机制还没用上,找个时间研究下。^^
7 楼
pedestrian_I
2006-10-07
谢谢各位了,唉,被投成垃圾贴了。是我的问题太菜了还是?
6 楼
Readonly
2006-10-06
string类型PK改到数字类型PK只能减少page lock,但是不能消除。
根本的解决方法是改序列号生成方法,像你这种在一个表里面记录最大值,然后不停累加,然后再更新到其他表,很容易出deadlock。
你可以将这个最大值在系统启动的时候从各个表读取,然后更新,并且把这个值放到内存中,这样在系统运行中的时候就不需要和这个表打交道了。
这里有一些其他技巧减少lock的资料,也可以参考一下:
http://www.sql-server-performance.com/reducing_locks.asp
根本的解决方法是改序列号生成方法,像你这种在一个表里面记录最大值,然后不停累加,然后再更新到其他表,很容易出deadlock。
你可以将这个最大值在系统启动的时候从各个表读取,然后更新,并且把这个值放到内存中,这样在系统运行中的时候就不需要和这个表打交道了。
这里有一些其他技巧减少lock的资料,也可以参考一下:
http://www.sql-server-performance.com/reducing_locks.asp
5 楼
关门放狗
2006-10-06
pagelock在我做的sql server项目中也经常碰到,想象就是明明用了rowlock,但是往往不是lock住一行,而且一个page内的row都被lock住了
象你这个需求,从实现方式上面就已经形成了一个瓶颈,所有的操作都集中在一个表上,要在上面取ID,并发的时候出现deadlock或者取出同一个id就是必然了,建议采用缓冲的机制,对于每个用户,他每次到ID表中取的ID的时候,都是取回一批ID,另外一个session来取得时候,拿到的是另外一批,然后这个用户在生成ID的时候,从这个缓冲中取,取尽的时候才重新去表中得到另外一批ID。
象你这个需求,从实现方式上面就已经形成了一个瓶颈,所有的操作都集中在一个表上,要在上面取ID,并发的时候出现deadlock或者取出同一个id就是必然了,建议采用缓冲的机制,对于每个用户,他每次到ID表中取的ID的时候,都是取回一批ID,另外一个session来取得时候,拿到的是另外一批,然后这个用户在生成ID的时候,从这个缓冲中取,取尽的时候才重新去表中得到另外一批ID。
4 楼
pedestrian_I
2006-10-05
Readonly 写道
关键字:Sql Server, 默认驱动,String类型的PK
在高并发下的page lock(而不是row lock)会出现死锁
和spring/hibernate没有任何关系
解决方法:
1. 换数据库......
2. 用jtds试试看
3. 用数字类型的PK试试看
在高并发下的page lock(而不是row lock)会出现死锁
和spring/hibernate没有任何关系
解决方法:
1. 换数据库......
2. 用jtds试试看
3. 用数字类型的PK试试看
page lock?不是很清楚引发它的原因!你可以不可以说得再仔细点呢?学习一下^^
换数据库是不能了,数据库和测试数据是检测中心给定的,现今就没办法改动了.因为时间也很紧张!
换jtds驱动包和改成int类pk,这个稍后去试试...待会看下结果.一直都知道string类型慢,但是引起并发lock那么严重就不知道了...经验尚浅
3 楼
Readonly
2006-10-05
关键字:Sql Server, 默认驱动,String类型的PK
在高并发下的page lock(而不是row lock)会出现死锁
和spring/hibernate没有任何关系
解决方法:
1. 换数据库......
2. 用jtds试试看
3. 用数字类型的PK试试看
在高并发下的page lock(而不是row lock)会出现死锁
和spring/hibernate没有任何关系
解决方法:
1. 换数据库......
2. 用jtds试试看
3. 用数字类型的PK试试看
2 楼
pedestrian_I
2006-10-04
其中SysBillManage就是POJO,是实体类,属性如下。
为了保证单例,我把service中的SysBillManage变量简单的改成了static
既是 ->private static SysBillManage sysBillManage;
但是问题依旧存在,同时并发时候getOrderNO()方法取得的单据号依然还是存在相同,既一个单号会被多次取出去,并没有同步。
另外,spring中的bean默认是单例模式,对吧?既然是,方法又做了同步,那为什么还是无法同步呢?
public class SysBillManage implements java.io.Serializable { private String billType;//主健 private String typePrefix;//前缀 private String startNumber;//开始号 private String codeFormat;//格式 private String currentNumber;//当前数量 private String remark; /** default constructor */ public SysBillManage() { } //getter... //setter... }
为了保证单例,我把service中的SysBillManage变量简单的改成了static
既是 ->private static SysBillManage sysBillManage;
但是问题依旧存在,同时并发时候getOrderNO()方法取得的单据号依然还是存在相同,既一个单号会被多次取出去,并没有同步。
另外,spring中的bean默认是单例模式,对吧?既然是,方法又做了同步,那为什么还是无法同步呢?
1 楼
dada
2006-10-04
private SysBillManage sysbillmanage;
有什么作用?
singleton否?
有什么作用?
singleton否?
相关推荐
但在高并发下,事务的隔离级别和死锁问题也需要关注和妥善处理。 四、最佳实践 1. 适当的线程池大小:根据服务器硬件配置和业务特性,合理设定线程池的大小,避免过度消耗资源或处理请求不及时。 2. 请求队列设计:...
一个经典的获取SQLSERVEr数据库死锁及引起锁定的进程的存储过程。执行时,必须具有数据库超级管理员权限。
死锁典型例题集锦 在操作系统原理中,死锁是一个非常重要的概念。死锁的出现可能会导致系统崩溃,...通过这些例子,我们可以看到死锁的出现是由于资源的竞争和互斥所引起的,了解死锁的机理和解决方法是非常重要的。
操作系统同步与死锁课件。并发进程、进程的交往:竞争和协作。临界区管理
在分布式系统中,集群同步锁是一种重要的机制,用于在多节点间协调操作,确保数据的一致性和完整性。Spring作为一款广泛使用的Java应用框架,提供了多种方式来实现集群同步锁。本篇文章将深入探讨如何利用Spring在...
在多任务环境中,死锁是一个严重的问题,指的是两个或多个并发进程互相等待对方释放资源而无法继续执行的情况。为了解决这个问题,银行家算法被引入,这是一种预防死锁的策略。本实验主要关注的就是银行家算法的实现...
一个详细讲解JAVA_线程同步与死锁的例子 希望可以帮助到你。
然而,这种同步通信模式可能导致死锁问题,即一组进程相互等待对方释放资源而无法继续执行,从而导致整个系统停滞。 死锁是并行和分布式计算中的一个重要问题,特别是在MPI环境中,因为多个进程可能同时执行,且...
死锁是操作系统中的一种严重状态,发生在两个或更多进程相互等待对方释放资源,导致所有进程都无法继续执行。解决死锁的关键在于预防、避免或检测与恢复。预防策略包括剥夺资源、避免策略(银行家算法)等;检测与...
进程、线程、死锁和POSIX规范的系统调用 进程是操作系统中一个独立的执行单元,它拥有自己的虚拟地址空间和系统资源。线程是轻量级的进程,它共享同一个进程的虚拟地址空间和系统资源。理解进程和线程的概念对于...
死锁是当两个或者以上的事务互相阻塞引起的。在这种情况下两个事务会无限期地等待对方释放资源以便操作。下面是死锁的示意图: 本文将使用SQLServer Profiler来跟踪死锁。 准备工作: 为了侦测...
死锁是指两个或多个事务在执行过程中,因争夺资源而造成的一种相互等待的现象,若无外力干涉它们将无法继续执行。死锁是数据库系统中常见的问题,尤其在多用户、高并发的应用场景下,了解和处理死锁显得尤为重要。 ...
从进程同步的概念可以知道,当并发进程需要竞争使用资源或需要相互协作向前推进时,如果不采取同步措施,或同步措施不恰当,则很容易导致并发进程不能向前推进而陷入僵局,即死锁现象。死锁是发生在一组相互竞争或...
死锁是多线程编程中一个严重的问题,它发生在两个或更多个线程相互等待对方释放资源,导致它们都无法继续执行。这种情况就像两个竞争对手在等待对方先退出,从而陷入无休止的等待状态。理解死锁的概念对于编写高效、...
3.1 并发进程 3.2 临界区管理 3.3 信号量与PV操作 3.4 管程 3.5 进程通信 3.6 死锁
"计算机操作系统课件:第4章进程同步与通信-死锁03.ppt" 本文总结了计算机操作系统中进程同步与通信的重要概念--死锁。死锁是指在多道程序系统中,一组进程中每个进程都无限等待被该组进程中另一进程所占有且永远...
希望能够对你对操作系统的学习带来帮助
死锁是指两个或多个并发进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力干涉它们都将无法推进下去。死锁的四个必要条件包括互斥条件、请求与保持条件、不剥夺条件和循环等待条件。在实验中,我们...