<< 十二月 2009 | 首页 | 二月 2010 >>

com.mchange.v2.resourcepool.ResourcePoolException: Attempted to use a closed or broken resource pool

解决这个异常需要修改设置成如下:

<property name="acquireRetryAttempts">
    <value>30</value>
</property>
<property name="acquireRetryDelay">
    <value>100</value>
</property>
<property name="breakAfterAcquireFailure">
    <value>false</value>
</property>

- acquireRetryAttempts 
Default: 30 
Defines how many times c3p0 will try to acquire a new Connection from the database before giving up. If this value is less than or equal to zero, c3p0 will keep trying to fetch a Connection indefinitely 

- acquireRetryDelay 
Default: 1000 
Milliseconds, time c3p0 will wait between acquire attempts. 

- breakAfterAcquireFailure 
Default: false 
If true, a pooled DataSource will declare itself broken and be permanently closeed if a Connection cannot be obtained from the database after making acquireRetryAttempts to acquire one. If false, failure to obtain a Connection will cause all Threads waiting for the pool to acquire a Connection to throw an Exception, but the DataSource will remain valid, and will attempt to acquire again following a call to getConnection().

 


标签 : , ,

Javascript Best Practices

 

Introduction

This document is a list of best practices and preferred ways of developing javascript code, based on opinions and experience from many developers in the javascript community. Since this is a list of recommendations rather than a list of absolute rules, experienced developers may have slightly differing opinions from those expressed below.


Table Of Contents

  1. Always Use 'var'
  2. Feature-Detect Rather Than Browser-Detect
  3. Use Square Bracket Notation
  4. Avoid 'eval'
  5. Reference Forms and Form Elements Correctly
  6. Avoid 'with' Statements
  7. Use onclick In Anchors Instead Of javascript: Pseudo-Protocol
  8. Use The Unary + Operator To TypeConvert To Number
  9. Avoid document.all
  10. Don't Use HTML Comments In Script Blocks
  11. Avoid Cluttering The Global Namespace
  12. Avoid sync "Ajax" calls
  13. Use JSON
  14. Use Correct <script> Tags

阅读全文……

标签 :

Spring, JdbcTemplate and Transactions

JdbcTemplate的事务问题

使用Spring的JdbcTemplate,必须传入DataSource对象构造JdbcTemplate,JdbcTemplate使用的Connection对象是一个新申请的,而且JdbcTemplate操作采用的是JDBC默认的AutoCommit模式,因此如果同时在一个DAO或者Service里混合用了HibernateTemplate和JdbcTemplate,甚至默认的配置情况下,使用同一个JdbcTemplate两次操作SQL也不是事务的。要让JdbcTemplate单独支持事务必须做一些编码或特殊的配置:

  

Yet another item in my dirty-secrets category is the fact that so far, until about a week ago, I had never used database transactions withSpring and JDBC, although I have been using Spring for more than 3 years now. Before Spring, I did a lot of classic JDBC coding with the try..catch..finally pattern. My first application using Spring was to wrap another third party application which updated its MySQLdatabases using JDBC as well. In a few instances we would add hooks to insert/update additional data using JDBC. Subsequently I discovered JdbcTemplate, but I was now working on applications where the main focus was transaction speeds and it was acceptable to lose a few records here and there, so we used MySQL with the MyISAM storage engine (which does not support transactions) was chosen. To the readers who are cringing in horror, I am happy to report that we only had about half an hour of downtime in about 3 years of operation because of data corruption, and that half hour included figuring out why our servers were hung and switching to the replication server.

At my current job, we are using Spring with Oracle. So far I did not have to use transactions in my Spring JDBC code. There is a lot of code written in classic JDBC (using transactions) in the application, and most of the work I had done so far was reading that data, which did not need transactions. However, sometime early last week, I had to write the Data Access Object for a bean which consisted of one parent table and three child tables with foreign key dependencies on the parent. The save() and delete() methods of this DAO needed to be transactional since all the JDBC operations needed to succeed or fail as a unit.

I have used transactions with Spring and Hibernate in a small project (also on MySQL, but with the InnoDb storage engine) before. However, since Spring-Hibernate usage is so widely documented on the web, the effort did not involve much understanding. Spring-JDBC usage gets significantly less coverage, perhaps because it is not as popular. I began by applying the prescriptive examples I found on the web, but no matter what I tried, Oracle would complain about missing foreign keys and throw an exception. It ultimately turned out to be an application bug, but the problem led me to read up on transactions, and look at Spring code and find out how the TransactionTemplate is implemented, etc, so happily, I now understand a little more about Spring and J2EE transactions than I did before.

Setting up the Transaction Manager

No matter what approach (Declarative or Programmatic) you take with making your Spring-JDBC code transactional, you will need aTransaction Manager. Spring provides a DataSourceTransactionManager which you can use if your application speaks to a single database, otherwise you may need to choose the appropriate JTA Transaction Manager implementation. Regardless, switching out theTransaction Manager just involves changing the bean definition below. Here is the definition:

1
2
3
4
5
6
7
8
9
  <!-- you should already have one of these -->
  <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    ...
  </bean>

  <!-- this should be added for transaction support -->
  <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
     <property name="dataSource" ref="dataSource"/>
  </bean>

The Programmatic Approach

My initial implementation was using the programmatic transaction approach using a TransactionTemplate to wrap the code that needs to be in a transaction. To do this, my DAO bean declared a dependency on the TransactionManager bean defined above.

1
2
3
4
  <bean id="myDao" class="com.mycompany.daos.MyDao">
    <property name="dataSource" ref="dataSource"/>
    <property name="transactionManager" ref="transactionManager"/>
  </bean>

Our DAO code has methods to select various attributes based on various input parameters (named getXXX() and findXXX() by convention) and a save() and delete() method that inserts and deletes the bean from the database. The additional things a transactional DAO must have is the reference and setter for the Transaction Manager, code to build a Transaction Template from the Transaction Manager, and a TransactionCallback to wrap the transactional bit of code. This is shown below:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class MyDao extends JdbcDaoSupport {

  private TransactionTemplate txTemplate;
  ...

  public void setTransactionManager(PlatformTransactionManager txManager) {
    this.txTemplate = new TransactionTemplate(txManager);
    this.txTemplate.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRED);
  }

  ...
  public int save(MyBean bean) throws Exception {
    final int savedBeanId = (beanId == 0 ? getNextBeanId() : beanId);
    txTemplate.execute(new TransactionCallbackWithoutResult() {
      public void doInTransactionWithoutResult(TransactionStatus status) {
        if (beanId == 0) {
          getJdbcTemplate().update("insert into beans(id,name) values (?,?)",
            new Object[] {savedBeanId, bean.getName()});
        } else {
          getJdbcTemplate().update("update partner set name=? where id=?",
            new Object[] {bean.getName(), savedBeanId});
        }
        for (String beanProp1 : bean.getProps1()) {
          getJdbcTemplate().update(
            "insert into bean_props1(bean_id,prop_value) values (?,?)",
             new Object[] {savedBeanId, beanProp1});
        }
        for (String beanProp2 : bean.getProps2()) {
          getJdbcTemplate().update(
            "insert into bean_props2(bean_id,prop_value) values (?,?)",
             new Object[] {savedBeanId, beanProp2});
        }
        for (String beanProp3 : bean.getProps3()) {
          getJdbcTemplate().update(
            "insert into bean_props3(bean_id,prop_value) values (?,?)",
            new Object[] {savedBeanId, beanProp3});
        }
      }
    });
    return savedBeanId;
  }
  ...
}

Note that I did not want to return anything from my TransactionCallback, so I used a TransactionCallbackWithoutResult object. If there is a need to pass a result back from the callback, you can use TransactionCallback instead.

The Declarative Approach

Spring and most authors recommend using the Declarative approach. With this approach, the DAO code has no reference to the TransactionTemplate. It is identical to a DAO which would have been written to work without transactions. The DAO itself is wrapped inside a TransactionProxyFactoryBean which provides the transactional behavior for the bean. The transactional behavior can be configured in the application context using XML. Our configuration to make the save() and delete() methods work within a transaction but leave the getXXX() methods alone would look like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
  <bean id="myDaoTarget" class="com.mycompany.daos.MyDao">
    <property name="dataSource" ref="dataSource"/>
  </bean>

  <bean id="myDao" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager" ref="transactionManager"/>
    <property name="target" ref="myDaoTarget"/>
    <property name="proxyTargetClass" value="true"/>
    <property name="transactionAttributes">
      <props>
        <prop key="*">PROPAGATION_REQUIRED,-Exception</prop>
        <prop key="get*">PROPAGATION_SUPPORTS</prop>
      </props>
    </property>
  </bean>

I used CGLIB proxying because I did not want to define an interface for MyDao, but if an interface was defined, I could have used standard Java interface based proxying as well. The resulting DAO code now looks identical to one without transactions.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class MyDao extends JdbcDaoSupport {
  ...
  public int save(MyBean bean) throws Exception {
    final int savedBeanId = (beanId == 0 ? getNextBeanId() : beanId);
    if (beanId == 0) {
      getJdbcTemplate().update("insert into beans(id,name) values (?,?)",
        new Object[] {savedBeanId, bean.getName()});
    } else {
      getJdbcTemplate().update("update partner set name=? where id=?",
        new Object[] {bean.getName(), savedBeanId});
    }
    for (String beanProp1 : bean.getProps1()) {
      getJdbcTemplate().update(
        "insert into bean_props1(bean_id,prop_value) values (?,?)",
        new Object[] {savedBeanId, beanProp1});
    }
    for (String beanProp2 : bean.getProps2()) {
      getJdbcTemplate().update(
        "insert into bean_props2(bean_id,prop_value) values (?,?)",
         new Object[] {savedBeanId, beanProp2});
    }
    for (String beanProp3 : bean.getProps3()) {
      getJdbcTemplate().update(
        "insert into bean_props3(bean_id,prop_value) values (?,?)",
        new Object[] {savedBeanId, beanProp3});
    }
    return savedBeanId;
  }
  ...
}

或者:

public void insert(){ 
JdbcTempalte jt=new JdbcTemplate(dataSource); 
jt.update(1); 
jt.update(2); 
} 

For both the transaction and declarative approaches, note that it is not necessary to have all the JDBC code in a single method. If we wanted to refactor our save() code into multiple doSaveMyBeanMain(), doSaveMyBeanProps1(), etc, methods, using either of the above approaches without any modification will retain the transactional behavior.

Conclusion

This post described two approaches to making the DAO transactional with Spring and JDBC. The approaches described here are not new, they are based on approaches detailed in Spring documentation and other web pages, but I do it in more of a prescriptive style, and in more detail. Hopefully, it will be helpful to people using transactions with JDBC and Spring.

References

The following documents helped me to understand transactions and how they are used within Spring and EJB3.

标签 : , , ,

DOM 的有效使用

DOM的有效使用

考虑到由 DOM 设计强加的限制,如何才能有效和高效的使用该规范呢?下面是使用 DOM 的几条基本原则和方针,以及使工作更方便的函数库。

基本原则

如果您遵循几条基本原则,您使用 DOM 的经验将会显著提高:

  • 不要使用 DOM 遍历文档。
  • 尽可能使用 XPath 来查找节点或遍历文档。
  • 使用较高级的函数库来更方便地使用 DOM。

这些原则直接从对常见问题的研究中得到。正如上面所讨论的,DOM 遍历是出错的主要原因。但它也是最常需要的功能之一。如何通过不使用 DOM 而遍历文档呢?

Path

XPath 是寻址、搜索和匹配文档的各个部分的语言。它是 W3C 推荐标准(Recommendation),并且在大多数语言和 XML 包中实现。您的 DOM 包可能直接支持 XPath 或通过加载件(add-on)支持。本文的样本代码对于 XPath 支持使用 Xalan 包。

XPath 使用路径标记法来指定和匹配文档的各个部分,该标记法与文件系统和 URL 中使用的类似。例如,XPath: /x/y/z 搜索文档的根节点 x ,其下存在节点 y ,其下存在节点 z 。该语句返回与指定路径结构匹配的所有节点。

更为复杂的匹配可能同时在包含文档的结构方面以及在节点及其属性的值中。语句 /x/y/* 返回父节点为 x  y 节点下的任何节点。 /x/y[@name='a'] 匹配所有父节点为 x  y 节点,其属性称为 name ,属性值为 a 。请注意,XPath 处理筛选空格文本节点以获得实际的元素节点 ― 它只返回元素节点。

详细探讨 XPath 及其用法超出了本文的范围。请参阅 参考资料获得一些优秀教程的链接。花点时间学习 XPath,您将会更方便的处处理 XML 文档。

DOM 的语言无关性设计为其带来了非常广泛的可应用性并使其在大量的系统和平台上得以实现。这样做的代价是:使 DOM 比为每个语言专门设计的 API 更困难且更缺乏直观性。

DOM 奠定了一个非常有效的基础,遵循一些简单的原则就可其上构建易于使用的系统。凝结了一大群用户智慧和经验的 DOM 未来版本正在设计之中,而且极有可能为这里讨论的问题提供解决方案。如 JDOM 这样的项目正在修改该 API 以获得更自然 Java 感觉,而且如本文中所述的技术可以帮助您使 XML 的操纵更方便、更简洁并且不易出错。利用这些项目且遵循这些用法模式以允许 DOM 成为基于 XML 项目的出色平台。

DOM解析XML、修改Node的属性:

package com.lph.html;

import java.io.*;
import java.util.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;

public class TestDom {
 public static void main(String arge[]) {
  long lasting = System.currentTimeMillis();
  try {
   File f = new File("D:/data_10k.xml");
   DocumentBuilderFactory factory = DocumentBuilderFactory
     .newInstance();
   DocumentBuilder builder = factory.newDocumentBuilder();
   Document doc = builder.parse(f);
   NodeList nl = doc.getElementsByTagName("VALUE");
   for (int i = 0; i < nl.getLength(); i++) {
    Node node=nl.item(i);
    node.getAttributes().getNamedItem("name").setNodeValue("www");
    
    System.out.print("车牌号码:"
      + doc.getElementsByTagName("NO").item(i)
        .getFirstChild().getNodeValue());
    System.out.println("车主地址:"
      + doc.getElementsByTagName("ADDR").item(i)
        .getFirstChild().getNodeValue());
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}

 

 

标签 : ,

Google考虑关闭中国谷歌运营及网站

Google考虑关闭中国谷歌运营及网站

谷歌在其官方博客上宣布,考虑关闭中国运营及网站Google.cn:

与其他很多著名组织一样,我们经常会碰到各种各样的网络攻击。去年12月中旬,我们检测到一次来自中国的,对我们集团网络设备高度精密和有针对性的网络攻击,在此次攻击中,谷歌公司的知识产权遭到窃取。我们很快就查清这并非只是一场单纯的安全事件。

首先,此次攻击并非仅仅针对谷歌。我们在调查中发现,至少有其他20家大型公司也成为了类似的攻击目标,这些公司所在的行业分布广泛---包括互联网、金融、科技、媒体和化工行业。我们目前正在通知这些公司,并与美国有关部门携手展开调查。

第二,我们有证据表明攻击者的主要目标是入侵中国人权活动者的Gmail邮箱账户。根据我们掌握的调查数据,我们确信他们的攻击还未能达此目的。只有两个Gmail账户有被侵入过的迹象,而入侵者的活动范围也仅限于账户信息(如账户创建时的数据)和邮件主题,而不是邮件内容。

第三,我们在对谷歌案件的调查中发现,有很多拥护人权活动,注册地在美国、中国和欧洲的Gmail邮箱账户似乎经常受到第三方侵入。入侵者并非是通过Google的安全漏洞进行攻击,而极有可能是通过在用户的电脑内植入钓鱼网页或是恶意软件来达到目的。

我们已经利用从这次攻击中所获取的资料,改善基础设施及架构,提高谷歌及我们用户的安全。从个人用户来说,我们我们建议他们在自己的电脑上安装信誉好的反病毒和反间谍软件程序,给他们的操作系统安装补丁,并更新所使用的网络浏览器。在点击即时信息和电子邮件的链接时,或要求在线提供个人密码等个人资料时,要保持警惕。在这里,你能够阅读到更多我们所提出的关于电子安全方面的建议。如果希望获得更多关于这种类型攻击情况,请阅读美国政府的这份报告(PDF)。

2006年1月,虽然我们对一些搜索结果将受到审查而感到不适,但为了加强与中国用户的联系以及建立一个更为开放的互联网环境,我们还是发布了Google.cn。从发布之日起我们就有着明确的运营思路---我们将仔细审视中国的运营环境,包括新法律的发布以及对我们所服务领域的其他规定。如果我们认为我们无法取得既定目标,我们将毫不犹豫的重新考虑我们在中国的发展策略。

 

这些未经报道的攻击和监视,以及过去几年来政府试图进一步限制互联网上的言论自由已使我们得出结论,我们应重新审视我们在中国的业务运营。我们已决定我们将不再继续审查Google.cn上的搜索结果,且如有可能的话,未来几周内我们将与中国政府就我们是否可以依法运营一个未经过滤的搜索引擎展开讨论。我们认识到这可能意味着我们不得不关闭Google.cn,并有可能关闭我们设在中国的办公部门。

以下为分析人士观点:

SOLARIS资产管理投资总监TIM GHRISKEY:

对谷歌和消费者而言显然都不是好消息。谷歌最好能找到解决途径,即使他们不得不关闭中国业务,也会有重新恢复的一天。我希望会很快恢复,不能想象谷歌永久性关闭中国业务。

对任何业务来说,中国都是巨大的增长引擎,谷歌也能在中国市场发现巨大商机。业界一定会找到对付黑客的方式,这也是时不时困扰很多其他公司的问题,也是用户的灾难。

标签 :

找出占用系统网络端口的根源

找出占用系统网络端口的根源 

 在windows 环境下面,从开始->运行,输入cmd,进入dos界面,然后输入如下命令并运行。

   view plaincopy to clipboardprint? 
C:\Documents and Settings\qingxu>netstat -aon|findstr "1371"  
  TCP    10.5.35.151:1371       203.208.37.104:80      CLOSE_WAIT      2160  
C:\Documents and Settings\qingxu>netstat -aon|findstr "1371" 
  TCP    10.5.35.151:1371       203.208.37.104:80      CLOSE_WAIT      2160

可以看到,运行命令后出现了一行记录,我们关注的是最后一个字段,对,就是2160,它表示占用这个端口的进程号。

 


有了进程号之后,继续输入如下命令并运行

view plaincopy to clipboardprint? 
C:\Documents and Settings\qingxu>tasklist|findstr "2160"  
Fiddler.exe                 2160 Console                 0    150,648 K  
C:\Documents and Settings\qingxu>tasklist|findstr "2160" 
Fiddler.exe                 2160 Console                 0    150,648 K 
 

可以看到,是fiddler.exe这个程序在运行。之后你就可以关闭掉这个程序即解决问题,当然你也可以换端口号。

 

标签 :

自定义Java 5 的新XPath API 函数

Java 5 的XPath API已经非常好用了,它实现了XPath1.0标准,功能已经比较强大了。

但是,还可以对它进行扩展,自定义XPath API 函数。例如,想要支持matches函数,以便匹配正则表达式,就可如下:

  XPathFactory factory = XPathFactory.newInstance();
  XPath xpath = factory.newXPath();
  
  xpath.setXPathFunctionResolver(new MatchesFunctionContext());
  xpath.setNamespaceContext(new MyNamespaceContext());

  
  XPathExpression expr = xpath.compile("//*[ext:matches(@href,\"/photos/.*/[0-9]+/\")]/IMG");

  Object result = expr.evaluate(doc, XPathConstants.NODESET);
  
  NodeList nodes;

  nodes = (NodeList) result;// XPathAPI.selectNodeList(doc, "//*[@id=\"Main\"]");
  System.out.println(nodes.getLength());
  for (int i = 0; i < nodes.getLength(); i++) {
//   System.out.println(nodes.item(i).getNodeName());
//   System.out.println(nodes.item(i).getTextContent());

   
  }

 

import javax.xml.namespace.QName;
import javax.xml.xpath.XPathFunction;
import javax.xml.xpath.XPathFunctionResolver;

public class MatchesFunctionContext implements XPathFunctionResolver{
   private static final QName name
    = new QName("http://ext.com", "matches");

   public XPathFunction resolveFunction(QName name, int arity) {

       if (name.equals(MatchesFunctionContext.name) ) {
           return new FuncMatches();
       }
       return null;
   }

}

import java.util.Iterator;

import javax.xml.namespace.NamespaceContext;

public class MyNamespaceContext implements NamespaceContext
{
    public String getNamespaceURI(String prefix)
    {
        if (prefix == null)
          throw new IllegalArgumentException("The prefix cannot be null.");
       
        if (prefix.equals("ext"))
            return "http://ext.com";
        else
            return null;
    }
   
    public String getPrefix(String namespace)
    {
        if (namespace == null)
          throw new IllegalArgumentException("The namespace uri cannot be null.");
        if (namespace.equals("http://ext.com"))
          return "ext";
        else
          return null;
    }

    public Iterator getPrefixes(String namespace)
    {
        return null;
    }

}

 


import java.util.List;

import javax.xml.xpath.XPathFunction;
import javax.xml.xpath.XPathFunctionException;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * Execute the Contains() function.
 *
 * @xsl.usage advanced
 */
public class FuncMatches implements XPathFunction {
 static final long serialVersionUID = 5084753781887919723L;

 /**
  *
  */
 public Object evaluate(List args) throws XPathFunctionException {

  if (args.size() != 2) {
   throw new XPathFunctionException(
     "Wrong number of arguments to valid-isbn()");
  }
  Object o = args.get(0);
  String s1 = null;
  if (o instanceof NodeList) {

   NodeList list = (NodeList) o;
   if (list.getLength() == 0) {
    return Boolean.FALSE;
   }

   Node node = list.item(0);
   // getTextContent is available in Java 5 and DOM 3.
   // In Java 1.4 and DOM 2, you'd need to recursively
   // accumulate the content.
   s1 = node.getTextContent();
  }

  String s2 = (String) args.get(1);

  // Add this check for JDK consistency for empty strings.
  if (s1.length() == 0 && s2.length() == 0)
   return Boolean.TRUE;

  boolean match = s1.matches(s2);
  return (match) ? Boolean.TRUE : Boolean.FALSE;
 }

}

标签 : ,