`
newslxw
  • 浏览: 207215 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

多线程下谨慎对待基类(抽象类)中的成员变量

阅读更多
有这么个需求:
做开发一套在oracle和mysql中做业务数据复制,其中具体的业务还没确定,目前需要开发一套
框架,需要在业务确定后,只需做少了开发即可实现,我使用了ibatis+spring
,以后扩展时,只需增加ibatis的配置文件即可,而配置文件中的每个ID都是由以下规则生成:
业务识别码+新增/删除等统一的后缀。
如下结构:

1、DAO部分
public abstract class Base
{
   private String name;
   private String code;
   public String getName(){return name;}
   public String getCode(){return code;}
   public void setName(String name){this.name=name;}
   public void setCode(String code){this.code = code;}

   public String getInsertSqlName()
   {
       return this.code+"insert";
   }

   public abstract insert(...);
   public abstract query(...);

}

public class ADao extends Base
{
       public map insert(...)
   {
      String sqlName = this.getInsertSqlName();
      //用ibatis操作数据库

   }

   public map query(...)
   {
      xxxxx
   }
}
public class  BDao extends Base
{
       public map insert(...)
   {
      String sqlName = this.getInsertSqlName();
      //用ibatis操作数据库

   }

   public map query(...)
   {
      xxxxx
   }
}

public class CDao extends Base
{
       public map insert(...)
   {
      String sqlName = this.getInsertSqlName();
      //用ibatis操作数据库

   }

   public map query(...)
   {
      xxxxx
   }
}



2、Service部分
   根据数据库配置动态创建DAO,大概如下:
   String name=从数据库读取
    String code = 从数据库读取
    Base dao = ServFactory.getDao(name,code);
   dao.insert(xxx);
   dao.query(xxx);


3、为了重用DAO,如上面Service部分,使用ServFactory创建DAO,
   原理就是将创建的DAO放到map中,在getDao前先检查map中有没有DAO,没有则创建。

单线程运行下没问题。

但是在并发处理时,发现查询出来的数据错位了,明明查A的数据,结果返回了B的数据。

使用debug跟踪发现,DAO中的name和code会在执行insert后的query被突然改变,原来在并发下有其他请求的code被其他获取相同DAO的线程改变,导致最后执行的SQL不是预期的SQL。

解决方法有2:
1、不缓存DAO,每次创建个新DAO

2、不适用Base的成员变量,直接将name和code通过参数传入到insert和query中

我选择了后者。
分享到:
评论

相关推荐

    Java开发技术大全(500个源代码).

    ThreadImRunnable.java 继承Runnable接口实现多线程 mulThread.java 创建多个线程对象的类 demoJoin.java 演示使用join()以确保主线程最后结束 clicker.java 一个计数用的线程类 demoPri.java 调用上面这个类...

    Visual C++开发经验技巧宝典(第1章)

    0062 如何利用抽象类进行数据封装 25 0063 数据类型与类对象大小的区别 26 0064 实现类的强制转换 26 1.8 高级函数 27 0065 如何重载操作符 27 0066 如何定义重载函数 28 0067 默认构造函数 28 0068 ...

    21天学通Java-由浅入深

    245 12.3.3 在外部类外访问静态内部类 246 12.4 匿名内部类 247 12.4.1 创建匿名内部类 247 12.4.2 匿名内部类的初始化 249 12.5 综合练习 250 12.6 小结 250 12.7 习题 250 第13章 多线程(精彩视频:55分钟) 252 ...

    java课程设计报告-五子棋(1).doc

    //包的定义 Import java.awt.Color //导入包关键字Import 4、接口 、接口的定义 Java中的接口可以看成是一种抽象类,它是一些抽象方法和常量的集合,其主要作用 是使得处于不同层次上以至于互不相干的类能够执行...

    java课程设计报告-五子棋.doc

    //包的定义 Import java.awt.Color //导入包关键字Import 4、接口 、接口的定义 Java中的接口可以看成是一种抽象类,它是一些抽象方法和常量的集合,其主要作用 是使得处于不同层次上以至于互不相干的类能够执行...

    java课程设计报告-五子棋(2).doc

    //包的定义 Import java.awt.Color //导入包关键字Import 4、接口 、接口的定义 Java中的接口可以看成是一种抽象类,它是一些抽象方法和常量的集合,其主要作用 是使得处于不同层次上以至于互不相干的类能够执行...

    java 面试题 总结

    与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...

    超级有影响力霸气的Java面试题大全文档

    与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...

    JAVA面试题最全集

    多线程,用什么关键字修饰同步方法?stop()和suspend()方法为何不推荐使用? 59.使用socket建立客户端与服务器的通信的过程 60.JAVA语言国际化应用,Locale类,Unicode 61.描述反射机制的作用 62.如何读写一个...

    net学习笔记及其他代码应用

    Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。 接口(interface)是抽象类的变体。在接口中,所有方法...

    在一小时内学会 C#(txt版本)

    默认情况下存在一个全局命名空间,所以在命名空间外定义的类直接进到此全局命名空间中,因而你可以不用定界符访问此类。 你同样可以定义嵌套命名空间。 Using #include 指示符被后跟命名空间名的 using 关键字代替...

    java面试笔试题大汇总

    与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。

    java面试题

    与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...

    C#本质论(第3版)

    6.3 抽象类 6.4 所有类都从system. object派生 6.5 使用is运算符验证基础类型 6,6使用as运算符进行转换 6.7 小结 第7章 接口 7.1 接口概述 7.2 通过接口来实现多态性 7.3 接口实现 7.3.1 显式成员实现 ...

    C#5.0本质论第四版(因文件较大传的是百度网盘地址)

    6.3 抽象类 204 6.4 所有类都从System.Object派生 208 6.5 使用is操作符验证基础类型 209 6.6 使用as操作符进行转换 210 6.7 小结 211 第7章 接口 213 7.1 接口概述 213 7.2 通过接口实现多...

    JAVA_API1.6文档(中文)

    java.util.concurrent.atomic 类的小工具包,支持在单个变量上解除锁的线程安全编程。 java.util.concurrent.locks 为锁和等待条件提供一个框架的接口和类,它不同于内置同步和监视器。 java.util.jar 提供读写 ...

    python cookbook(第3版)

    8.12 定义接口或者抽象基类 8.13 实现数据模型的类型约束 8.14 实现自定义容器 8.15 属性的代理访问 8.16 在类中定义多个构造器 8.17 创建不调用init方法的实例 8.18 利用Mixins扩展类功能 8.19 实现状态...

Global site tag (gtag.js) - Google Analytics