4

Microsoft SQL Server データベースに接続された Flex/BlazeDS/Spring/JPA/Hibernate Web アプリケーションに取り組んでいます。テーブルをあまりにも積極的にロックしているようです。私の調査によると、スナップショット分離ポリシーを使用するのが最善の策のようです。

私は次のように設定しました:

  <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" lazy-init="true">
    <property name="persistenceUnitName" value="OrderManagerPersistenceUnit" />
    <property name="dataSource" ref="dataSource"/>
     <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
     </property>
    <property name="jpaProperties">
      <props>
        <prop key="hibernate.jdbc.batch_size">${db.main.hibernate.jdbc.batch_size}</prop>
        <prop key="hibernate.hbm2ddl.auto">${db.main.hbm2ddl.auto}</prop>
        <prop key="hibernate.search.default.indexBase">${db.main.search.default.indexBase}</prop>
        <prop key="hibernate.search.autoregister_listeners">${db.main.search.autoregister_listeners}</prop>
          <prop key="hibernate.show_sql">${db.main.show_sql}</prop>
          <prop key="hibernate.dialect">${db.main.dialect}</prop>
          <prop key="hibernate.connection.isolation">${db.main.isolation}</prop>
          <prop key="hibernate.ejb.naming_strategy">com.herffjones.zebra.db.ZebraNamingStrategy</prop>
      </props>
    </property>
  </bean>

ただし、実際に hibernate.connection.isolation を使用しているとは確信していません。JDBC データソースにもいくつかのプロパティを設定する必要があるようです。

現在、クエリのトランザクション分離レベルとして 4096 を使用しているかどうかを確認したいと思います。

特定のクエリが使用している分離レベルを明確に確認するために、logback.xml ファイルに追加できるパッケージとログ レベルは何ですか?

ありがとう!

4

3 に答える 3

7

hibernate のトランザクション分離レベルを 2 (READ_COMMITTED の java.sql.Connection 定数) に設定する必要があります。

次に、SQL Server 2005 インスタンスで次を実行します (アクティブな接続はありません)。

ALTER DATABASE [database_name] SET ALLOW_SNAPSHOT_ISOLATION ON; ALTER DATABASE [データベース名] SET READ_COMMITTED_SNAPSHOT ON;

次のクエリを実行してテストします。

SELECT [名前]、snapshot_isolation_state_desc、snapshot_isolation_state、is_read_committed_snapshot_on FROM sys.databases WHERE [名前] = 'データベース名';

READ_COMMITTED は、SQL Server で READ_COMMITTED_SNAPSHOT として解釈されるようになりました。

于 2010-09-22T15:17:32.257 に答える
2

DataSourceを指定すると、Hibernate はhibernate.connection.isolation設定を無視します。

代わりに、DataSource レベルで分離レベルを設定する必要があります。ほとんどの接続プールまたは XA Java EE アプリケーション サーバー データソースでは、グローバル トランザクション分離レベルを設定できるため、そのデータソースからのすべての接続は同じ分離レベルを継承します。

于 2014-12-24T07:16:36.080 に答える
2

JPA/MySQL で発生した問題について説明したいと思います。それはあなたの調査を刺激するかもしれません...

  • グローバル取引開始
  • transaction 1) テーブル Address の新しい行 (自動インクリメント)
  • トランザクション 2) テーブル Entreprise の新しい行と、テーブル アドレスの外部キー。挿入された新しい Entreprise は、新しいアドレス #ID にリンクされます。
  • グローバル取引終了

この場合、MYSQL は ResourceLocal / JPATransactionManager でデッドロックします。

実際、ネストされた複数のトランザクションを開くことはできないようです。グローバルトランザクションは、トランザクション 1) および 2) とマージされているようです。トランザクション 2) は、準備ができていないテーブル A 新しい #Id でデータをフィードできないため、デッドロックで終了します。

ただし、デバッガーを使用すると、トランザクション 1 と 2 の間の新しいアドレス row#id を確認できます。

あなたの問題に似ていますか?自動インクリメントを推測しますか - デッドロックとの関係はありますか? これらの以下は可能な解決策です...

  • Solution1 分離レベルを変更しますか? -> どのように ? !!私には答えがありません...そして、これが何かを変えるとは確信していません。

  • 解決策 2 JPA エンティティ ID 生成戦略 (自動または ID) をカスタム シーケンス テーブルに置き換えます。

  • ソリューション3

ManyToOne 関係でカスケード戦略を使用できないかどうかを確認してください。

EntrepriseEntity{
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "id_entreprise")
private int id;

@ManyToOne(fetch=FetchType.LAZY,cascade=CascadeType.ALL)
@JoinColumn(name = "id_address")
private AddressEntity address;  

次に、両方の行を単一の merge() に保存します。

EntrepriseEntity e=new EntrepriseEntity();
e.setAddress(new AddressEntity());
e=entityManager.merge(e);

返されたインスタンスは、挿入された新しい #ids と魔法の両方を返します。デッドロックはなくなりました...

解決策 #3 はよりスマートですが、より深い分析といくつかのコードの変更が必要です...

于 2010-07-29T16:55:34.063 に答える