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 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 オブジェクトはデフォルトでシングルトンであることを知っています。これは、各スレッドが 1 つのオブジェクトしか持たないということですか、それとも JVM インスタンス全体が 1 つのオブジェクトしか持たないということですか? これらの 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 の間にデータベース設計があることは知っていますが、これはこの問題の範囲を超えています。このクラスをシングルトンとして作成したにもかかわらず、この関数が同時実行の問題を引き起こす可能性があるかどうかに興味がありますか?

4

2 に答える 2

1

あなたの問題から、スレッドセーフ性がSpringとは何の関係もないことは明らかです。

たとえば、うまくいかない可能性のある場所がたくさんある可能性があります:(よく知られたパターンではないように見えるので、BOが何を意味するのか本当にわかりません。「ユーザー」がBOでメソッドを呼び出し、BOがDAO を呼び出してデータ取得ジョブを実行します)

セッションファクトリーをどのように使用していますか? 私はあなたが1つのセッションを受けていないことを望み、それを使い続けます. それをどのように使用するかについて、いくつかのコード スニペットを示すことは素晴らしいことです。

BO がシングルトンの場合、個々の「ユーザー セッション」の状態を保持しますか? スレッドセーフではない処理で使用される共有オブジェクトはありますか?

データの取得と更新であるDAOに関連する問題について、デッドロックを回避するための作業を行いましたか? たとえば、関数 A はテーブル X を更新してからテーブル Y を更新し、関数 B は Y を更新してから X を更新します。2 人のユーザーが同じレコードを更新している場合、後者の更新が前者を暗黙のうちに上書きしないことを確認する作業を行いましたか? 1 つ (更新がべき等でない場合)。

問題の原因はたくさんありますが、その 99.999% は Spring (または Hibernate) とは関係がないと考えています。

于 2012-12-06T02:11:37.470 に答える
0

問題は解決しました。これは、DB2 がテーブルに新しい列を追加して同時実行の問題を処理できず、それを主キーにしたことが原因です。

于 2012-12-16T10:00:55.760 に答える