myJavaBlog

java世界
随笔 - 43, 文章 - 0, 评论 - 2, 引用 - 0
数据加载中……

教你如何用java取得web工程目录

     摘要: 1.可以在servlet的init方法里 String path = getServletContext().getRealPath("/"); 这将获取web项目的全路径 例如 :E:\eclipseM9\workspace\tree\ tree是我web项目的根目录 2.你也可以随时在任意的class里调用 this.getClass...  阅读全文

posted @ 2012-04-19 09:39 夏凡 阅读(7806) | 评论 (1)编辑 收藏

教你如何使用Maven模板生成一个项目

     摘要: Maven带有超过40+个Maven模板,让开发者快速开始一个新的Java项目。这一章,演示怎样使用Maven的命令“mvn archetype:generate”生成一个新的Java Web项目。 下面是使用Maven模板生成项目的步骤。 1、mvn archetype:generate命令 定位到要生成的项目的目录下,如“D:\...  阅读全文

posted @ 2012-04-19 09:33 夏凡 阅读(2087) | 评论 (0)编辑 收藏

教你认识和理解spring声明式事务管理

Spring也提供了声明式事务管理。这是通过Spring AOP实现的。 

Spring 中进行事务管理的通常方式是利用AOP(面向切片编程)的方式,为普通java类封装事务控制,它是通过动态代理实现的,由于接口是延迟实例化的, spring在这段时间内通过拦截器,加载事务切片。原理就是这样,具体细节请参考jdk中有关动态代理的文档。本文主要讲解如何在spring中进行事务控制。 
动态代理的一个重要特征是,它是针对接口的,所以我们的dao要通过动态代理来让spring接管事务,就必须在dao前面抽象出一个接口,当然如果没有这样的接口,那么spring会使用CGLIB来解决问题,但这不是spring推荐的方式,所以不做讨论. 

大多数Spring用户选择声明式事务管理。这是最少影响应用代码的选择, 因而这是和非侵入性的轻量级容器的观念是一致的。 

从考虑EJB CMT和Spring声明式事务管理的相似以及不同之处出发是很有益的。 它们的基本方法是相似的:都可以指定事务管理到单独的方法;如果需要可以在事务上 下文调用setRollbackOnly()方法。不同之处如下: 

不象EJB CMT绑定在JTA上,Spring声明式事务管理可以在任何环境下使用。 只需更改配置文件,它就可以和JDBC、JDO、Hibernate或其他的事务机制一起工作 

Spring可以使声明式事务管理应用到普通Java对象,不仅仅是特殊的类,如EJB 

Spring提供声明式回滚规则:EJB没有对应的特性, 我们将在下面讨论这个特性。回滚可以声明式控制,不仅仅是编程式的 

Spring允许你通过AOP定制事务行为。例如,如果需要,你可以在事务 回滚中插入定制的行为。你也可以增加任意的通知,就象事务通知一样。使用 EJB CMT,除了使用setRollbackOnly(),你没有办法能 够影响容器的事务管理 

Spring不提供高端应用服务器提供的跨越远程调用的事务上下文传播。如 果你需要这些特性,我们推荐你使用EJB。然而,不要轻易使用这些特性。通常我 们并不希望事务跨越远程调用 

回滚规则的概念是很重要的:它们使得我们可以指定哪些异常应该发起自 动回滚。我们在配置文件中,而不是Java代码中,以声明的方式指定。因此,虽然我们仍 然可以编程调用TransactionStatus对象的 setRollbackOnly()方法来回滚当前事务,多数时候我们可以 指定规则,如MyApplicationException应该导致回滚。 这有显著的优点,业务对象不需要依赖事务基础设施。例如,它们通常不需要引 入任何Spring API,事务或其他任何东西。 

EJB的默认行为是遇到系统异常(通常是运行时异常), EJB容器自动回滚事务。EJB CMT遇到应用程序异常 (除了java.rmi.RemoteException外的checked异常)时不 会自动回滚事务。虽然Spring声明式事务管理沿用EJB的约定(遇到unchecked 异常自动回滚事务),但是这是可以定制的。 

按照我们的测试,Spring声明式事务管理的性能要胜过EJB CMT。 

通常通过TransactionProxyFactoryBean设置Spring事务代理。我们需要一个目标对象包装在事务代理中。这个目标对象一般是一个普通Java对象的bean。当我们定义TransactionProxyFactoryBean时,必须提供一个相关的 PlatformTransactionManager的引用和事务属性。 事务属性含有上面描述的事务定义。 

<bean id="petStore"     class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">   
<property name="transactionManager"><ref bean="transactionManager"/></property> 
    <property name="target"><ref bean="petStoreTarget"/></property>  
  <property name="transactionAttributes">        <props>            <prop key="insert*">PROPAGATION_REQUIRED,-MyCheckedException</prop>            <prop key="update*">PROPAGATION_REQUIRED</prop>            <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>        </props>    </property></bean> 
code] 
事务代理会实现目标对象的接口:这里是id为petStoreTarget的bean。(使用 CGLIB也可以实现具体类的代理。只要设置proxyTargetClass属性为true就可以。如果目标对象没有实现任何接口,这将自动设置该属性为true。通常,我们希望面向接口而不是类编程。)使用proxyInterfaces属性来限定事务代理来代 理指定接口也是可以的(一般来说是个好想法)。也可以通过从 org.springframework.aop.framework.ProxyConfig继承或所有AOP代理工厂共享 的属性来定制TransactionProxyFactoryBean的行为。 

这里的transactionAttributes属性定义在 org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource 中的属性格式来设置。这个包括通配符的方法名称映射是很直观的。注意 insert*的映射的值包括回滚规则。添加的-MyCheckedException 指定如果方法抛出MyCheckedException或它的子类,事务将 会自动回滚。可以用逗号分隔定义多个回滚规则。-前缀强制回滚,+前缀指定提交(这允许即使抛出unchecked异常时也可以提交事务,当然你自己要明白自己 在做什么)。 

TransactionProxyFactoryBean允许你通过 “preInterceptors”和“postInterceptors”属性设置“前”或“后”通知来提供额外的 拦截行为。可以设置任意数量的“前”和“后”通知,它们的类型可以是 Advisor(可以包含一个切入点), MethodInterceptor或被当前Spring配置支持的通知类型 (例如ThrowAdvice, AfterReturningtAdvice或BeforeAdvice, 这些都是默认支持的)。这些通知必须支持实例共享模式。如果你需要高级AOP特 性来使用事务,如有状态的maxin,那最好使用通用的 org.springframework.aop.framework.ProxyFactoryBean, 而不是TransactionProxyFactoryBean实用代理创建者。 

也可以设置自动代理:配置AOP框架,不需要单独的代理定义类就可以生成类的 代理。 

附两个spring的事务配置例子: 
<prop key="add"> 
     PROPAGATION_REQUIRES_NEW, -MyException 
</prop> 
注:上面的意思是add方法将独占一个事务,当事务处理过程中产生MyException异常或者该异常的子类将回滚该事务。 

<prop key="loadAll"> 
    PROPAGATION_SUPPORTS, ISOLATION_READ_COMMITED, Readonly 
</prop> 
注:表示loadAll方法支持事务,而且不会读取没有提交事务的数据。它的数据为只读(这样有助于提高读取的性能) 

附A Spring中的所有事务策略 

PROPAGATION_MANDATORY 
PROPAGATION_NESTED 
PROPAGATION_NEVER 
PROPAGATION_NOT_SUPPORTED 
PROPAGATION_REQUIRED 
PROPAGATION_REQUIRED_NEW 
PROPAGATION_SUPPORTS 

附B Spring中所有的隔离策略: 

ISOLATION_DEFAULT 
ISOLATION_READ_UNCOMMITED 
ISOLATION_COMMITED 
ISOLATION_REPEATABLE_READ 
ISOLATION_SERIALIZABL 
(转载请注明出处:[url=http://www.a9832.com]博彩网[/url]
[url=http://www.tswa.org]博彩通[/url])

posted @ 2012-04-18 21:16 夏凡 阅读(325) | 评论 (0)编辑 收藏

认识java反射与代理

     摘要: java反射与代理 一. 关于数据库. 当今的数据处理大致可以分成两大类:联机事务处理OLTP(on-line transaction processing)、联机分析处理OLAP(On-Line Analytical Processing)。OLTP是传统的关系型数据库的主要应用,主要是基本的、日常的事务处理,例如银行交易。OLAP是数据仓库系统的主要应用,支持复杂的分析操作...  阅读全文

posted @ 2012-04-18 21:14 夏凡 阅读(249) | 评论 (0)编辑 收藏

分享关于JMS与WebService负载均衡

众所周知,当多个消息消费者(MessageConsumer)同时监听同一个消息队列(Queue)的时候,JMS提供者会在它们之间提供一种负载均衡机制,从而达到可以同时处理多个消息的目的。图一是一个简单的示意图,当消息生产者发送多个消息时,JMS提供者会把这些消息均匀的分发到不同的消息消费者。  


  图一 JMS负载均衡示意图

  一、WebService负载均衡
  要在原来的WebService上应用负载均衡,首先应该明确一个前提,就是客户端和服务端应尽可能的不做修改。另外还需要确保可以方便的添加和删除一个Service节点,而不会影响整个应用的运行。庆幸的是WebService调用通常都是无状态的,类似于无状态会话 Bean(Stateless Session Bean)的远程调用,服务端和客户端不需要维持一个会话,也就是说同一个客户端调用多次WebService请求,每个请求可以由不同的Service 为它服务,这样就可以避免Session复制的问题,如果一个Service崩溃了,另一个Service可以继续为客户端服务。
  二、将JMS负载均衡应用到WebService中
  接下来就把JMS的负载均衡机制应用到WebService当中去,图二是一个整体的框架图,Proxy作为一个WebService的代理来和客户端交互, 而Listener会去掉用具体的WebService,来完成一次WebService方法的调用。


  图二 整体框架图

  与客户端直接交互的是Proxy,它是一个简单的Servlet,它的作用就是拦截客户端发送过来的请求,提取请求中的SOAP包的内容,然后把它封装成一个消息发送到指定的Queue中去,同时它会等待消息的回复,因为回复的消息中包含着WebService调用返回的结果,后面会详细讲到。当Proxy收到回复消息之后,读取其中的内容并把它返回给客户端,从而完成一个WebService的调用。另外需要注意的是,在这里Proxy需要区分出客户端发出的是GET请求,还是POST请求。如果是GET请求,就有可能是客户端正在获取WebService的WSDL。如果是POST请求,那么通常就是客户端在调用一个WebService方法了。下面是一个简单的Proxy实现:
  1   public class ServiceProxy extends HttpServlet {
  2
  3   private ConnectionFactory factory;
  4
  5   private Connection connection;
  6
  7   private Queue queue;
  8
  9   public void init() throws ServletException {
  10
  11   super.init();
  12
  13   try {
  14
  15   //在这里为了简单起见,采用了ActiveMQ。在实际的J2EE应用中应通过JNDI查找相应的ConnectionFactory和Queue。|||
  16
  17   factory = new ActiveMQConnectionFactory("vm://localhost");
  18
  19   connection = factory.createConnection();
  20
  21   connection.start();
  22
  23   queue = new ActiveMQQueue("testQueue");
  24
  25   } catch (JMSException e) {
  26
  27   e.printStackTrace();
  28
  29   }
  30
  31   }
  32
  33   protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
  34
  35   if (req.getQueryString().endsWith("wsdl") || req.getQueryString().endsWith("WSDL")) {
  36
  37   try {
  38
  39   Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
  40
  41   Message message = session.createMessage();
  42
  43   //这个属性用来标示请求是否是WSDL请求,后面的Listener会根据它来调用具体的WebService。
  44
  45   message.setBooleanProperty("isWsdl", true);
  46
  47   message.setJMSReplyTo(session.createTemporaryQueue());
  48
  49   session.createProducer(queue).send(message);
  50
  51   //等待回复消息,它里面包含Service返回的WSDL,这里使用了一个选择器。
  52
  53   String selector = String.format("JMSCorrelationID=‘%s‘", message.getJMSMessageID());
  54
  55   MessageConsumer consumer = session.createConsumer(message.getJMSReplyTo(), selector);
  56
  57   TextMessage replyMessage = (TextMessage) consumer.receive();
  58
  59   //将WSDL返回给客户端。
  60
  61   resp.getWriter().write(replyMessage.getText());
  62
  63   } catch (Exception e) {
  64
  65   e.printStackTrace();
  66
  67   }
  68
  69   }
  70
  71   }
  72
  73   protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
  74
  75   try {
  76
  77   //首先从客户端请求中得到SOAP请求部分。
  78
  79   StringBuffer payLoad = new StringBuffer();
  80
  81   BufferedReader reader = req.getReader();
  82
  83   String temp;
  84
  85   while ((temp = reader.readLine()) != null) {
  86
  87   payLoad.append(temp);
  88
  89   }
  90
  91   //将SOAP请求封装成一个消息,发送到Queue。
  92
  93   Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
  94
  95   Message message = session.createTextMessage(payLoad.toString());
  96
  97   message.setBooleanProperty("isWsdl", false);
  98
  99   message.setJMSReplyTo(session.createTemporaryQueue());
  100|||
  101   session.createProducer(queue).send(message);
  102
  103   //等待回复,回复的消息中包含着服务端返回的SOAP响应。
  104
  105   String selector = String.format("JMSCorrelationID=‘%s‘", message.getJMSMessageID());
  106
  107   MessageConsumer consumer = session.createConsumer(message.getJMSReplyTo(), selector);
  108
  109   TextMessage replyMessage = (TextMessage) consumer.receive();
  110
  111   //将SOAP响应返回给客户端。
  112
  113   resp.getWriter().write(replyMessage.getText());
  114
  115   } catch (Exception e) {
  116
  117   e.printStackTrace();
  118
  119   }
  120
  121   }
  122
  123   }
  接下来需要看一下Listener了。对于每一个Service都有一个Listener与之相对应,当一个Listener从Queue中取得一个消息之后,首先应该判断是否是WSDL请求。如果是WSDL请求,则向WebService发送一个GET请求,并将请求的结果,也就是WSDL封装成一个Message回复给Proxy。如果是SOAP请求,则从中取出SOAP请求部分并通过POST方法发送给Service,所得到的返回结果即为Service的SOAP响应,把它回复给Proxy,进而回复给客户端。
  下面是Listener的一个简单实现,在这里我们使用了HttpClient来发送GET和POST请求。
  1   public class Listener {
  2
  3   private ConnectionFactory factory;
  4
  5   private Connection connection;
  6
  7   private Queue queue;
  8
  9   private Session session;
  10
  11   public Listener() throws Exception {
  12
  13   //为了简单,还是采用了ActiveMQ。
  14
  15   factory = new ActiveMQConnectionFactory("vm://localhost");
  16
  17   connection = factory.createConnection();
  18
  19   connection.start();
  20
  21   queue = new ActiveMQQueue("testQueue");
  22
  23   session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
  24
  25   }
  26
  27   public void startUp() throws Exception {
  28
  29   MessageConsumer consumer = session.createConsumer(queue);
  30
  31   consumer.setMessageListener(new MessageListener() {
  32
  33   public void onMessage(Message message) {
  34
  35   try {
  36
  37   String response;
  38
  39   //通过判断isWSDL这个属性来判断是否是WSDL请求。
  40
  41   if (message.getBooleanProperty("isWsdl")) {
  42
  43   //如果是WSDL请求,则向服务器发送一个GET请求,并等待WSDL响应结果。
  44
  45   HttpClient client = new HttpClient();|||
  46
  47   //具体Service的地址,可以使用properties文件等。
  48
  49   GetMethod m = new GetMethod("http://localhost:8081/hello?wsdl");
  50
  51   client.executeMethod(m);
  52
  53   response = m.getResponseBodyAsString();
  54
  55   } else {
  56
  57   //如果是SOAP请求,则将SOAP包发送给服务器,并等待SOAP响应。
  58
  59   HttpClient client = new HttpClient();
  60
  61   PostMethod m = new PostMethod("http://localhost:8081/hello");
  62
  63   m.setRequestBody(((TextMessage) message).getText());
  64
  65   client.executeMethod(m);
  66
  67   response = m.getResponseBodyAsString();
  68
  69   }
  70
  71   //将WSDL响应或SOAP响应封装成一个消息,回复给Proxy。
  72
  73   MessageProducer producer = session.createProducer(message.getJMSReplyTo());
  74
  75   TextMessage replyMessage = session.createTextMessage(response);
  76
  77   //设置JMSCorrelationID,Proxy通过它来得到该回复消息。
  78
  79   replyMessage.setJMSCorrelationID(message.getJMSCorrelationID());
  80
  81   producer.send(replyMessage);
  82
  83   } catch (Exception ex) {
  84
  85   ex.printStackTrace();
  86
  87   }
  88
  89   }
  90
  91   });
  92
  93   }
  94
  95   }
  三、还需要考虑的
  1,如果其中一个Service崩溃,我们需要停止相应的Listener,这一点可以在Listener中做到,例如当Listener访问 Service时出错,它可以等待一段时间以后再去监听Queue,同时把已经取得的消息重新发回到Queue中去,以便让其他的Listener处理。当然也可以将Listener放置到Service端,这样Service崩溃,Listener也就跟着不可用了。
  2,如果某一时刻,所有的Service都不可用,Proxy也不应该无限等待下去,而应该设置一个等待回复消息的超时期限,如果这个期限内没有收到回复消息,则表明Service都不可用,同时通知客户端。
  3,过期消息的处理,如同上一点,当Service不可用时,Proxy通知客户端出错,但是此时Proxy已经向Queue中发送了一条消息,当Service恢复时,这条消息会被重新处理。我们应该避免这种情况发生,因为这条消息已经过期了。可以设置消息的过期期限小于Proxy等待回复消息的期限,以确保它不会被重新处理。
  4,最糟糕的情况就是,Proxy或者Queue崩溃,这样就算Service正常,客户端也会调用失败。
  5,效率,既然我们选择了WebService和负载均衡,那就表示我们应该接受它效率相对低下的弱点,在这里需要说明的是JMS并不是效率的瓶颈,因为Listener只负责拿到消息并发送给Service,这时Service还是运行在多线程下的。
(转载请注明出处:[url=http://www.6rfd.com]澳门博彩[/url]

[url=http://www.9gds.com]易博网[/url]

posted @ 2012-04-18 20:30 夏凡 阅读(427) | 评论 (0)编辑 收藏

对java hashCode的详细解读

hashCode就是我们所说的散列码,使用hashCode算法可以帮助我们进行高效率的查找,例如HashMap,说hashCode之前,先来看看Object类。

我们知道,Object类是java程序中所有类的直接或间接父类,处于类层次的最高点。在Object类里定义了很多我们常见的方法,包括我们要讲的hashCode方法,如下

 

Java代码  收藏代码
  1. public final native Class<?> getClass();  
  2. public native int hashCode();  
  3. public boolean equals(Object obj) {  
  4.   return (this == obj);  
  5. }   
  6. public String toString() {  
  7.  return getClass().getName() + "@" +  Integer.toHexString(hashCode());  
  8. }  

注意到hashCode方法前面有个native的修饰符,这表示hashCode方法是由非java语言实现的,具体的方法实现在外部,返回内存对象的地址。


在java的很多类中都会重写equals和hashCode方法,这是为什么呢?最常见的String类,比如我定义两个字符相同的字符串,那么对它们进行比较时,我想要的结果应该是相等的,如果你不重写equals和hashCode方法,他们肯定是不会相等的,因为两个对象的内存地址不一样。


String类的重写的hashCode方法

Java代码  收藏代码
  1. public int hashCode() {  
  2.     int h = hash;  
  3.     if (h == 0) {  
  4.         int off = offset;  
  5.         char val[] = value;  
  6.         int len = count;  
  7.   
  8.             for (int i = 0; i < len; i++) {  
  9.                 h = 31*h + val[off++];  
  10.             }  
  11.             hash = h;  
  12.         }  
  13.         return h;  
  14.     }  

1、这段代码究竟是什么意思?

其实这段代码是这个数学表达式的实现

Java代码  收藏代码
  1. s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]  

 s[i]是string的第i个字符,n是String的长度。那为什么这里用31,而不是其它数呢?《Effective Java》是这样说的:之所以选择31,是因为它是个奇素数,如果乘数是偶数,并且乘法溢出的话,信息就会丢失,因为与2相乘等价于移位运算。使用素数的好处并不是很明显,但是习惯上都使用素数来计算散列结果。31有个很好的特性,就是用移位和减法来代替乘法,可以得到更好的性能:31*i==(i<<5)-i。现在的VM可以自动完成这种优化


2、它返回的hashCode有什么特点呢?

可以看到,String类是用它的value值作为参数来计算hashCode的,也就是说,相同的value就一定会有相同的hashCode值。这点也很容易理解,因为value值相同,那么用equals比较也是相等的,equals方法比较相等,则hashCode一定相等。反过来不一定成立。它不保证相同的hashCode一定有相同的对象。


一个好的hash函数应该是这样的:为不相同的对象产生不相等的hashCode。

在理想情况下,hash函数应该把集合中不相等的实例均匀分布到所有可能的hashCode上,要想达到这种理想情形是非常困难的,至少java没有达到。因为我们可以看到,hashCode是非随机生成的,它有一定的规律,就是上面的数学等式,我们可以构造一些具有相同hashCode但value值不一样的,比如说:Aa和BB的hashCode是一样的。


说到这里,你可能会想,原来构造hash冲突那么简单啊,那我是不是可以对HashMap函数构造很多<key,value>不都一样,但具有相同的hashCode,这样的话可以把HashMap函数变成一条单向链表,运行时间由线性变为平方级呢?虽然HashMap重写的hashCode方法比String类的要复杂些,但理论上说是可以这么做的。这也是最近比较热门的Hash Collision DoS事件。

HashMap里重写的hashCode方法

Java代码  收藏代码
  1. public final int hashCode() {  
  2.     return (key==null   ? 0 : key.hashCode()) ^  
  3.             (value==null ? 0 : value.hashCode());  
  4.  } 
    (转载请注明出处:[url=http://www.k8764.com]博彩通[/url]

    [url=http://www.5sfd.com]e世博[/url]

posted @ 2012-04-18 19:55 夏凡 阅读(6054) | 评论 (0)编辑 收藏

教你如何在JS端将JSON对象转化为字符串的方法

由于工作需要,要在JS端将JSON对象转化为字符串,并写到用户的COOKIE中,用来保存用户的一些个人操作习惯。便在网上搜寻了一遍,发现方法有很多,有些代码不清晰,看得乱,有些考虑不周全,生成的字符串有问题,便整合了一些好的写法,自己改进了一下。可能还是考虑得不周全,但是感觉常用的类型都考虑了,望大家多多拍砖指点!

JSON.stringify(jsonobj),本来是最简便的方法,可是存在浏览器兼容问题(仅适用于IE8+,Chrome 1+,FF 3+)。

var O2String = function (O) {
        //return JSON.stringify(jsonobj);

        var S = [];
        var J = "";
        if (Object.prototype.toString.apply(O) === '[object Array]') {
            for (var i = 0; i < O.length; i++)
                S.push(O2String(O[i]));
            J = '[' + S.join(',') + ']';
        }
        else if (Object.prototype.toString.apply(O) === '[object Date]') {
            J = "new Date(" + O.getTime() + ")";
        }
        else if (Object.prototype.toString.apply(O) === '[object RegExp]' || Object.prototype.toString.apply(O) === '[object Function]') {
            J = O.toString();
        }
        else if (Object.prototype.toString.apply(O) === '[object Object]') {
            for (var i in O) {
                O[i] = typeof (O[i]) == 'string' ? '"' + O[i] + '"' : (typeof (O[i]) === 'object' ? O2String(O[i]) : O[i]);
                S.push(i + ':' + O[i]);
            }
            J = '{' + S.join(',') + '}';
        }

        return J;
    };

/*-----------------------以下是测试代码-----------------------*/ var jsonStr = O2String( [ { "Page": "plan", "Custom": [ { "ItemName": "CustomLabel1", "ItemContent": 1, "IsItem": true, "ItemDate": new Date(1320774905467), "ItemReg": /[\w]*?/gi, "ItemFunc": function () { alert("ItemFunc"); } }, { "ItemName": "CustomLabel1", "ItemContent": 1, "IsItem": true, "ItemDate": new Date(1320774905467), "ItemReg": /[\w]*?/gi, "ItemFunc": function () { alert("ItemFunc"); } } ] }, { "Page": "project", "Custom": [ { "ItemName": "CustomLabel2", "ItemContent": 2, "IsItem": false, "ItemDate": new Date(1320774905467), "ItemReg": /[\w]*?/gi, "ItemFunc": function () { alert("ItemFunc"); } }, { "ItemName": "CustomLabel2", "ItemContent": 2, "IsItem": false, "ItemDate": new Date(1320774905467), "ItemReg": /[\w]*?/gi, "ItemFunc": function () { alert("ItemFunc"); } } ] } ] ); alert(jsonStr); var jsonObj = eval("(" + jsonStr + ")"); alert(jsonObj.length);
(转载请注明出处:[url=http://www.tdtf.org]易博网
[/url] [url=http://www.k5048.com]博彩网[/url]


posted @ 2012-04-18 19:47 夏凡 阅读(513) | 评论 (0)编辑 收藏

你懂得在v$session 中查找locking信息吗?

现象:
系统突然报连接数过高,基本的现象就是有什么东西被锁了,导致后续的连接都在等待,那么到底是那个会话导致了阻塞那?
可以查看视图v$session ,关注以下几个字段
sid-------------------------被阻塞的进程id
status--------------------被阻塞的进程状态
COMMAND--------------被阻塞的进程执行的命令
ROW_WAIT_FILE#----被阻塞的进程对应的rowid所在的数据文件id
row_wait_block#-----row_wait_row#对应的rowid所在的表的object id
row_wait_obj#-------row_wait_row#对应的rowid所在的表的object id
row_wait_row#-----Current row being locked. This column is valid only if the session is currently waiting for another transaction to commit and the value of ROW_WAIT_OBJ# is not -1.但是准确的说是对应的于rowid的rownum,并非是单纯的rownum
blocking_session -----阻塞进程id
STATE-------------------被阻塞进程的状态
EVENT#----------------被阻塞进程等待的事件号
EVENT------------------被阻塞进程等待的事件
-----注意create_time是程序自动添加的
select t.sid,t.status,t.COMMAND,t.ROW_WAIT_FILE#,t.row_wait_block#,t.row_wait_obj#,t.row_wait_row#,t.blocking_session ,t.STATE,t.EVENT#,t.EVENT from temp_session t where t.BLOCKING_SESSION_STATUS='VALID' and t.create_time=to_date('2012/3/20 18:47:16','yyyy/mm/dd hh24:mi:ss');

SID  STATUS COMMAND ROW_WAIT_FILE# ROW_WAIT_BLOCK# ROW_WAIT_OBJ# ROW_WAIT_ROW# BLOCKING_SESSION STATE EVENT# EVENT
175 620  ACTIVE 3  8 571147  77418 17  885 WAITING  239 enq: TX - row lock contention
174 616  ACTIVE 3  8 571147  77418 17  885 WAITING  239 enq: TX - row lock contention
173 615  ACTIVE 3  8 571147  77418 17  885 WAITING  239 enq: TX - row lock contention
333 1050  ACTIVE 3  8 571147  77418 17  885 WAITING  239 enq: TX - row lock contention
179 632  ACTIVE 3  8 571147  77418 17  885 WAITING  239 enq: TX - row lock contention
178 629  ACTIVE 3  8 571147  77418 17  885 WAITING  239 enq: TX - row lock contention
332 1049  ACTIVE 3  8 571147  77418 17  885 WAITING  239 enq: TX - row lock contention
171 610  ACTIVE 3  8 571147  77418 17  885 WAITING  239 enq: TX - row lock contention
166 592  ACTIVE 3  8 571147  77418 17  885 WAITING  239 enq: TX - row lock contention
165 591  ACTIVE 3  8 571147  77418 17  885 WAITING  239 enq: TX - row lock contention
164 589  ACTIVE 3  8 571147  77418 17  885 WAITING  239 enq: TX - row lock contention

现在可以看到885进程阻塞了好多进程,那么要获得到底是那条记录被锁定了那?

想要知道某一个表具体被锁定的是哪一行,可以利用上面这几个值,查找出被锁定行的rowid。
使用dbms_rowidb包的一个子过程(Subprograms)rowid_create
DBMS_ROWID.ROWID_CREATE (
rowid_type IN NUMBER,
object_number IN NUMBER,
relative_fno IN NUMBER,
block_number IN NUMBER,
row_number IN NUMBER)
RETURN ROWID;
其中rowid_type的取值为 0 表示生成一个restricted ROWID(pre-oracle8 format); 取值为1 表示生成一个extended ROWID.
object_number取值是dba_objects视图中的data_object_id,并不是object_id,也就是说不能用row_wait_obj#.
relative_fno取值是Relative文件号,在dba_data_files里可以查到
block_number取值是数据文件的块号,也就是v$session中的row_wait_block#的值
row_number通过rowid对应出来的rownum,也就是row_wait_row#的值。

接下来找到这些数据
rowid_type=1(11g)
object_number
selectdata_object_id from dba_objects where object_id='77418'
OBJECT_IDTT_BIGINT NOT NULLDictionary object number of the object.
DATA_OBJECT_IDTT_BIGINTIs ignored.----这是11g的文档说明,可以看出,使用object_id就可以
relative_fno=8
block_number=row_wait_block#
row_number =row_wait_row#

select * from table_name t where rowid=(
select DBMS_ROWID.ROWID_CREATE(1,77418,8,571147,17) from dual);---得到被锁定的记录;

此时查看885进程在做神马?
kill之就可以 
(转载请注明出处:[url=http://www.k6567.com]e世博[/url]
[url=http://www.d9732.com]澳门博彩[/url])

posted @ 2012-04-18 19:45 夏凡 阅读(213) | 评论 (0)编辑 收藏

教你如何处理隐式转换导致的负载过高的问题

现象:
突然系统报警负载过高
下面的处理步骤:
1、找到占用cpu高的进程
select tc.sql_text,tb.machine from v$process ta,v$session tb,
v$sql tc
where ta.addr=tb.PADDR
and tb.SQL_HASH_VALUE=tc.HASH_VALUE
and ta.SPID=31128
2、找到进程执行的sql






可以看到使用的了索引跳跃扫描


查看
select * from table(dbms_xplan.display_cursor('7b0908u6wx1ab'));




从这个就可以看到进行了隐式转换导致index skip scan的选择性过低,导致负载急升
(转载请注明出处:[url=http://www.a9832.com]博彩网[/url]
[url=http://www.tswa.org]博彩通[/url]

posted @ 2012-04-18 19:42 夏凡 阅读(140) | 评论 (0)编辑 收藏

有关MFC的 基础(实例)

#include <windows.h>
#include <stdio.h>

LRESULT CALLBACK WinSunProc(//名字可以更改。参数类型不能变
HWND hwnd, // handle to window 窗口句柄
UINT uMsg, // message identifier 
WPARAM wParam, // first message parameter 消息参数
LPARAM lParam // second message parameter
);
/*
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // pointer to command line
int nCmdShow // show state of window
);

*/
int WINAPI WinMain(//Windows程序的入口函数
HINSTANCE hInstance, // handle to current instance 当前实例句柄
HINSTANCE hPrevInstance, // handle to previous instance 前次实例句柄
LPSTR lpCmdLine, // command line 命令行参数
int nCmdShow // show state 显示方式
)
{
/*
创建一个完整的窗口需要经过下面四个操作步骤:
1、设计一个窗口类;
2、注册窗口类;
3、创建窗口;
4、显示及更新窗口。

typedef struct _WNDCLASS { 
UINT style; //类的类型
WNDPROClpfnWndProc; //longpointfunction函数指针
int cbClsExtra; //类的附加内存
int cbWndExtra; //窗口附加内存
HANDLE hInstance; //实例号(句柄)
HICON hIcon; //图标句柄
HCURSOR hCursor; //光标句柄
HBRUSH hbrBackground; //画刷句柄
LPCTSTR lpszMenuName; //菜单的名字
LPCTSTR lpszClassName; //类的名字
} WNDCLASS; 
*/
//1、设计一个窗口类;
WNDCLASS wndcls;//窗口类
wndcls.style=CS_HREDRAW | CS_VREDRAW;//重画垂直方向、水平方向
wndcls.lpfnWndProc=WinSunProc;//函数地址
wndcls.cbClsExtra=0;//类的附加内存
wndcls.cbWndExtra=0;//窗口的附加内存
wndcls.hInstance=hInstance;//实例号
wndcls.hIcon=LoadIcon(NULL,IDI_ERROR);//图标 设置
wndcls.hCursor=LoadCursor(NULL,IDC_CROSS);//光标 设置
wndcls.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);//画刷的句柄
wndcls.lpszMenuName=NULL;//(菜单名字)
wndcls.lpszClassName="VCXTU";//注册类名(longpoint命令行参数)

//2、注册窗口类;
RegisterClass(&wndcls);//注册类

/*
HWND CreateWindow(
LPCTSTR lpClassName, // pointer to registered class name
LPCTSTR lpWindowName, // pointer to window name
DWORD dwStyle, // window style
int x, // horizontal position of window
int y, // vertical position of window
int nWidth, // window width
int nHeight, // window height
HWND hWndParent, // handle to parent or owner window
HMENU hMenu, // handle to menu or child-window identifier
HANDLE hInstance, // handle to application instance
LPVOID lpParam // pointer to window-creation data
);
*/
//3、创建窗口;
HWND hwnd;//窗口句柄
hwnd=CreateWindow(
"VCXTU",//注册类名(lpszClassName)
"湖南省湘潭市湘潭大学",//窗口名字
/*
WS_OVERLAPPEDWINDOW:
窗口风格 
WS_OVERLAPPED 层叠的 具有标题栏和边框
WS_CAPTION 有标题栏
WS_SYSMENU 带有系统菜单
WS_THICKFRAME 具有可调边框
WS_MINIMIZEBOX 具有最小化按钮
WS_MAXIMIZEBOX) 具有最大化按钮
*/
WS_OVERLAPPEDWINDOW,//窗口风格 
CW_USEDEFAULT,//窗口水平坐标(缺省的)
CW_USEDEFAULT,//窗口垂直坐标(缺省的)
600,//窗口宽度
400,//窗口高度
NULL,// 父窗口句柄(hWndParent/handle to parent or owner window)
NULL,// 菜单句柄(handle to menu or child-window identifier)
hInstance,//句柄(handle to application instance)
NULL//窗口参数(pointer to window-creation data)
);

/*
BOOL ShowWindow(
HWND hWnd, // handle to window
int nCmdShow // show state of window
);
*/
//4、显示及更新窗口。
ShowWindow(
hwnd,//窗口句柄
SW_SHOWNORMAL//显示状态 show state of window
);
UpdateWindow(hwnd);//可有可无

/*
操作系统将每个事件都包装成一个称为消息的结构体MSG来传递给应用程序
MSG结构定义如下: 
typedef struct tagMSG { 
HWND hwnd; 
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
} MSG; 
*/
//消息循环
MSG msg;
/*
BOOL GetMessage(
LPMSG lpMsg, // address of structure with message
HWND hWnd, // handle of window
UINT wMsgFilterMin, // first message
UINT wMsgFilterMax // last message
);
*/
while(
GetMessage(
&msg,
NULL,
0,//设成0。表示对所有消息都有兴趣
0
)
)
{
/*
转换消息。可以将WM_KEYUP/WM_KEYDOWN转换为WM_CHAR消息、产生新消息并放到队列中
BOOL TranslateMessage(
CONST MSG *lpMsg // address of structure with message
);
*/
TranslateMessage(&msg);
/*
将收到的消息传到窗口的回调函数:wndcls.lpfnWndProc=WinSunProc;回调函数:WinSunProc
LONG DispatchMessage(
CONST MSG *lpmsg // pointer to structure with message
);
*/
DispatchMessage(&msg);
}
return 0;
}

LRESULT CALLBACK WinSunProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
switch(uMsg)
{
case WM_CHAR://表示按下了某个字符按键
char szChar[20];
sprintf(szChar,"char is %d",wParam);//格式化消息。WM_CHAR中的wParam参数
/*
int MessageBox(
HWND hWnd, //拥有消息的父窗口 handle of owner window
LPCTSTR lpText, //文本 address of text in message box
LPCTSTR lpCaption, //标题 address of title of message box
UINT uType //消息框的风格 style of message box
);
*/
MessageBox(
hwnd,
szChar,
"湘潭大学",//标题
MB_OKCANCEL//MB_YESNO//消息框的风格
);
break;
case WM_LBUTTONDOWN:
MessageBox(hwnd,"鼠标左键点击了","湘潭大学",MB_OKCANCEL);
HDC hdc;//句柄 handle to device context
/*
HDC GetDC(
HWND hWnd // handle to a window
);
*/
hdc=GetDC(hwnd);
/*
BOOL TextOut(
HDC hdc, // handle to device context
int nXStart, // x-coordinate of starting position
int nYStart, // y-coordinate of starting position
LPCTSTR lpString, // pointer to string
int cbString // number of characters in string
); 
*/
TextOut(hdc,0,50,"湖南省湘潭市湘潭大学1",strlen("湖南省湘潭市湘潭大学1"));
ReleaseDC(hwnd,hdc);//释放DC
break;
case WM_PAINT://窗口重绘
HDC hDC;
PAINTSTRUCT ps;
/*
HDC BeginPaint(
HWND hwnd, // handle to window
LPPAINTSTRUCT lpPaint
// pointer to structure for paint information
);
*/
hDC=BeginPaint(hwnd,&ps);//只能在WM_PAINT里面使用
TextOut(hDC,0,0,"湖南省湘潭市湘潭大学hDC",strlen("湖南省湘潭市湘潭大学hDC"));
EndPaint(hwnd,&ps);//只能在WM_PAINT里面使用
break;
case WM_CLOSE://关闭窗口时响应
if(IDYES==MessageBox(hwnd,"是否真的结束?","湘潭大学",MB_YESNO))
{
DestroyWindow(hwnd);//销掉hwnd窗口 还会发送 WM_DESTROY、WM_NCDESTROY 消息
}
break;
case WM_DESTROY:
PostQuitMessage(0);//退出程序
break;
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
}
(转载请注明出处:[url=http://www.live588.org]淘金盈[/url]

[url=http://www.10086money.com]时尚资讯[/url]

posted @ 2012-04-18 19:39 夏凡 阅读(307) | 评论 (0)编辑 收藏

仅列出标题
共5页: 上一页 1 2 3 4 5 下一页