我可以通过在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个成功地将数据插入到数据库中,1个挂起,1个在操作中丢失,这意味着没有响应,Websphere Application Server中没有捕获日志。有3个用户同时使用该应用程序的测试用例失败了,我可以知道当有1000个用户同时使用该应用程序时,我怎么能确保所有这些都是线程安全的?
更新
回应@Adrian Shum查询:
关于BO的事情,我不确定这是什么模式。但我是BOC代表业务对象控制器,拥有这个单元类的目的是将业务逻辑与DAO对象分开。最终这将结束XHTML / JSP是前端,BO是业务控制器,DAO关注hibernate和查询构造。
为了检索会话工厂,每个DAO对象都必须扩展HibernateDaoSupport,这就是Spring-Hibernate Integration根据本教程工作的方式。以下是一些代码段:
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(从属)和TableB(主)彼此有关系。我知道TableA和TableB之间有一个数据库设计,但这超出了这个问题。我只是好奇这个函数是否会导致并发问题,即使我把这个类作为单例?
答案 0 :(得分:1)
从您的问题来看,显然线程安全性与Spring无关。
可能有很多地方可能出错,例如:(我真的不知道你的BO意味着什么,因为它似乎不是一个众所周知的模式。我假设你的“用户”将在BO中调用方法和BO将调用DAO来执行数据检索工作)
你是如何使用会话工厂的?我希望你没有参加一个会议并继续使用它。如何显示一些关于如何使用它的代码片段会很棒。
如果您的BO是单身人士,它是否会为个人“用户会话”保留任何状态?处理中使用的任何共享对象都不是线程安全的吗?
与DAO相关的问题是数据检索和更新,您是否已完成了避免死锁的工作?例如,函数A将更新表X然后更新表Y,而函数B更新Y然后是X.您是否已完成工作以确保对于2个用户更新相同记录,后者更新将不会以静默方式覆盖前者一个(如果更新不是幂等的。)
导致你的问题可能有很多原因,但我相信其中99.999%与Spring(或Hibernate)无关。
答案 1 :(得分:0)
我解决了问题。这是因为DB2无法通过向表中添加新列来处理并发问题,并将其作为主键。