0

我可以通过像这样在Spring中配置数据源来知道:

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName" value="jdbc/dev"/>
  <property name="lookupOnStartup" value="false"/>
  <property name="cache" value="true"/>
  <property name="proxyInterface" value="javax.sql.DataSource"/>
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  <property name="dataSource">
    <ref bean="dataSource"/>
  </property>
  ...
</bean>

并像这样在 Spring 中配置我的 BOC 和 DAO 对象:

<bean id="Dao" class="com.dao.impl.DaoImpl">
  <property name="sessionFactory" ref="sessionFactory"/>
</bean>

<bean id="Bo" class="com.bo.impl.BoImpl">
  <property name="theDao">
    <ref local="Dao"/>
  </property>
</bean>

目前我正在用 3 个用户对其进行测试,1 个成功地将数据插入 DB,1 个挂起,1 个在操作中丢失,这意味着没有响应,Websphere Application Server 中没有捕获日志。有 3 个用户同时使用该应用程序未通过测试用例,当有 1000 个用户同时使用该应用程序的情况下,我能否知道如何确保所有这些都是线程安全的?


更新

回应@Adrian Shum 查询:

关于 BO 的事情,我不确定这是什么模式。但我是 BOC 是 Business Object Controller 的代表,拥有这个单元类的目的是将业务逻辑与 DAO 对象分离。最终这将导致 XHTML/JSP 是前端,BO 是业务控制器,而 DAO 是关注休眠和查询构造。

为了检索会话工厂,每个 DAO 对象都必须扩展 HibernateDaoSupport,这就是本教程中 Spring-Hibernate 集成的工作方式。这是一些代码片段:

class DAO extends HibernateDaoSupport implements IDao {

  public void save( Pojo pojo ) {
    getHibernateTemplate().save(pojo);
  }

  public void update( Pojo pojo ) {
    getHibernateTemplate().update(pojo);
  }

  public void delete( Pojo pojo ) {
    getHibernateTemplate().delete(pojo);
  }
}

我知道 Spring 对象默认是单例的。这是否意味着每个线程将只有一个对象或整个 JVM 实例将只有一个对象?如果我像这样将这些 BO 和 DAO 对象声明为会话范围怎么办:

<bean id="Dao" class="com.dao.impl.DaoImpl" scope="session">
  <property name="sessionFactory" ref="sessionFactory"/>
</bean>

<bean id="Bo" class="com.bo.impl.BoImpl" scope="session">
  <property name="theDao">
    <ref local="Dao"/>
  </property>
</bean>

关于数据更新或检索,这可能会发生,因为我们正在测试的 3 个用户实际上针对的是同一记录。可能有一个锁,因为我注意到有一个函数在执行此代码:

Query queryA = session.createQuery("Delete From TableA where fieldA = :theID");
queryA.setParameter("theID", "XX");
queryA.executeUpdate();

Query queryB = session.createQuery("Delete From TableB where fieldB = :theID");
queryB.setParameter("theID", "YY");
queryB.executeUpdate();

// update tableB object
session.save(tableBObj);

// update each tableA object
for(TableAObj obj : TableAObjList) {                
  session.save(obj);
  session.flush();
  session.evict(obj);
}

TableA(slave) 和 TableB(master) 之间有关系。我知道 TableA 和 TableB 之间有一个数据库设计,但这超出了这个问题。我只是好奇这个函数是否会导致并发问题,即使我把这个类设为单例?

4

2 回答 2

1

从您的问题来看,显然线程安全与 Spring 无关。

可能有很多地方会出错,例如:(我真的不知道你的 BO 是什么意思,因为它似乎不是一个众所周知的模式。我假设你的“用户”将调用 BO 中的方法,而 BO 会调用 DAO 来完成数据检索工作)

您如何使用会话工厂?我希望你没有得到一个会话并继续使用它。展示一些关于如何使用它的代码片段会很棒。

如果您的 BO 是单身人士,它是否会为单个“用户会话”保留任何状态?处理中使用的任何共享对象是否不是线程安全的?

对于与 DAO 相关的问题,即数据检索和更新,您是否已采取措施避免死锁?例如,函数 A 将更新表 X 然后表 Y,而函数 B 更新 Y 然后 X。您是否已完成工作以确保对于更新同一记录的 2 个用户,后者的更新不会默默地覆盖前者一个(如果更新不是幂等的)。

可能有很多原因导致您的问题,但我相信其中 99.999% 与 Spring(或 Hibernate)无关。

于 2012-12-06T02:11:37.470 回答
0

I have the problem resolved. It is due to the DB2 failed to handle concurrency issues by adding a new column into the table, and make it as a primary key.

于 2012-12-16T10:00:55.760 回答