Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在数据访问层中使用同步_Java_Performance_Caching_Synchronization_Data Access Layer - Fatal编程技术网

Java 在数据访问层中使用同步

Java 在数据访问层中使用同步,java,performance,caching,synchronization,data-access-layer,Java,Performance,Caching,Synchronization,Data Access Layer,假设我们正在开发一个类,该类实现了简单的CRUD操作来处理DB。此类还维护缓存以提高性能 public class FooTableGateway { Map<Integer, Foo> id2foo = new HashMap<Integer, Foo> (); public void getFoo (int id) { if (id2foo.containsKey (id) { return id2foo.get (id);

假设我们正在开发一个类,该类实现了简单的CRUD操作来处理DB。此类还维护缓存以提高性能

public class FooTableGateway {
   Map<Integer, Foo> id2foo = new HashMap<Integer, Foo> ();
   public void getFoo (int id) {
      if (id2foo.containsKey (id) {
          return id2foo.get (id);
      }
      String query = "select ...";
      Connection cn = null;
      Statement st = null;
      ResultSet rs = null;
      try {
          cn = DBUtils.getConnection ();
          st = cn.createStatement ();
          rs = st.executeQuery (query);

          if (!rs.next ()) {
              return null;
          }
          Foo foo = new Foo (rs.getString (1)...);
          id2foo.put (id, foo);
          return foo;
      } catch (SQLException e) {
          ..
      } finally {
          ..
      }
   }

   public boolean addFoo (Foo foo) {
      if (id2foo.values ().contains (foo) {
           return false;
      }
      String query = "insert into ...";
      Connection cn = null;
      Statement st = null;
      ResultSet rs = null;
      try {
          cn = DBUtils.getConnection ();
          st = cn.createStatement ();
          int num = st.executeUpdate (query.toString (),
                  Statement.RETURN_GENERATED_KEYS);
          rs = st.getGeneratedKeys ();
          rs.next ();  
          foo.setId (rs.getInt (1);
          id2foo.put (foo.getId (), foo);
          return true;
      } catch (SQLException e) {
          ..
          return false;
      } finally {
          ..
      }    
   }

   public void updateFoo (Foo foo) {
      //something similar
      ..
   }

   public boolean deleteFoo (int id) {
      //something similar
      ..
   }

}
公共类FooTableGateway{
Map id2foo=newhashmap();
公共void getFoo(int-id){
if(id2foo.containsKey(id){
返回id2foo.get(id);
}
字符串查询=“选择…”;
连接cn=null;
语句st=null;
结果集rs=null;
试一试{
cn=DBUtils.getConnection();
st=cn.createStatement();
rs=st.executeQuery(查询);
如果(!rs.next()){
返回null;
}
Foo-Foo=新的Foo(rs.getString(1)…);
id2foo.put(id,foo);
返回foo;
}捕获(SQLE异常){
..
}最后{
..
}
}
公共布尔addFoo(Foo-Foo){
if(id2foo.values().contains)(foo){
返回false;
}
字符串查询=“插入…”;
连接cn=null;
语句st=null;
结果集rs=null;
试一试{
cn=DBUtils.getConnection();
st=cn.createStatement();
int num=st.executeUpdate(query.toString(),
语句。返回\u生成的\u键);
rs=st.getGeneratedKeys();
rs.next();
foo.setId(rs.getInt(1);
id2foo.put(foo.getId(),foo);
返回true;
}捕获(SQLE异常){
..
返回false;
}最后{
..
}    
}
公共void updateFoo(Foo-Foo){
//类似的东西
..
}
公共布尔deleteFoo(int-id){
//类似的东西
..
}
}
问题是:应该同步哪部分代码?(当然,我们正在开发web应用程序)。
如果我要同步对缓存集合的所有调用,那么我甚至不确定使用缓存是否会提高性能。

哇……对于一个方法来说,这是很多代码。我真的建议将其分解为方法和对象,一次处理一件事

在上面给出的代码中,您应该在读、写和删除时同步缓存集合;这将锁定缓存,因此无法并行读取


编写一个高性能的线程安全缓存并不容易(特别是如果您现在或将来需要将其集群化的话)。您应该看看现有的缓存,如EHCache()或JBoss cache().

哇……对于一个方法来说,代码太多了。我真的建议将它分解为方法和对象,一次处理一件事情

在上面给出的代码中,您应该在读、写和删除时同步缓存集合;这将锁定缓存,因此无法并行读取


编写一个高性能的线程安全缓存并不容易(特别是如果您现在或将来需要对其进行集群化的话)。您应该仔细看看现有的缓存,如EHCache()或JBoss cache()。

编写的这段代码有太多问题

我认为DAO不应该与获取到数据库的连接有任何关系;它应该传入或注入到类中。DAO无法知道它是否正在更大的事务上下文中使用。应该使用一个单独的服务层,其方法对应于了解工作单元的用例负责获取连接、设置事务和隔离、封送DAO和业务实体以完成用例、提交或回滚事务以及清理资源

在这里,你有很多事情要做:持久性、缓存等等。如果你能开始剥离其中一些责任,把它们放到别处,你的生活会更好。我认为你的网关做得太多了

更新:

你扔到你的类中的映射告诉我这是一个巨大的错误。我没有看到任何软引用来帮助垃圾收集器。我没有看到任何努力来限制缓存的大小或更新值。这是一种自找麻烦的方法。编写缓存是一项巨大的努力。如果你不相信eve me,下载EhCache的源代码,并将其与您的地图进行比较。这不是小事

声明性事务没有逻辑——这是另一个巨大的错误

恕我直言,我会重新考虑这个实施方案


更好的建议是学习Spring和/或Hibernate。

编写的代码有太多问题

我认为DAO不应该与获取到数据库的连接有任何关系;它应该传入或注入到类中。DAO无法知道它是否正在更大的事务上下文中使用。应该使用一个单独的服务层,其方法对应于了解工作单元的用例负责获取连接、设置事务和隔离、封送DAO和业务实体以完成用例、提交或回滚事务以及清理资源

在这里,你有很多事情要做:持久性、缓存等等。如果你能开始剥离其中一些责任,把它们放到别处,你的生活会更好。我认为你的网关做得太多了

更新:

你扔到你的类中的映射告诉我这是一个巨大的错误。我没有看到任何软引用来帮助垃圾收集器。我没有看到任何努力来限制缓存的大小或更新值。这是一种自找麻烦的方法。编写缓存是一项巨大的努力。如果你不相信eve me,下载EhCache的源代码,并将其与您的地图进行比较。这不是小事

声明性事务没有逻辑——这是另一个巨大的错误

恕我直言,我会侦察的
  if (id2foo.containsKey (id) {
      return id2foo.get (id);
  }
  id2foo.put (id, foo);
Map<Integer, Foo> id2foo = new HashMap<Integer, Foo> ();