2010-07-21 41 views
4

我正在處理一個連接到Microsoft SQL Server數據庫的Flex/BlazeDS/Spring/JPA/Hibernate Web應用程序。它似乎在鎖定桌面過於積極。從我的研究看來,使用快照隔離策略看起來是最好的選擇。記錄JDBC/Hibernate/JPA事務隔離級別

我做一些事情,因爲這樣:

<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文件中,以清楚地看到特定查詢正在使用的隔離級別?

謝謝!

回答

6

您應該將hibernate的事務隔離級別設置爲2(READ_CO的java.sql.Connection常量MMITTED。

然後(沒有活動連接)執行你的SQL Server 2005以下實例:

ALTER DATABASE [數據庫名稱] SET ALLOW_SNAPSHOT_ISOLATION ON; ALTER DATABASE [database_name] SET READ_COMMITTED_SNAPSHOT ON;

測試通過執行該查詢:

SELECT [名稱],snapshot_isolation_state_desc,snapshot_isolation_state,is_read_committed_snapshot_on FROM sys.databases中 WHERE [名稱] = 'DATABASE_NAME';

現在,在SQL Server中,READ_COMMITTED將被解釋爲READ_COMMITTED_SNAPSHOT。

2

我想描述一下我在JPA/MySQL上遇到的問題;它可以激發你的調查......

  • 全球交易開始
  • 交易1)上表地址 (自動增量)
  • 交易2)新 行的表企業公司與外國 新行在地址上鍵入地址;插入的新的 企業鏈接到 新的地址#ID。
  • 結束全局事務的

MYSQL死鎖這種情況與ResourceLocal/JpaTransactionManager接口。

實際上,我們似乎無法打開幾個嵌套事務。全球交易似乎與交易1)和2)合併。事務2)以死鎖結束,因爲數據不能用表格提供新的#Id沒有準備好。

然而,我們可以用調試器看到交易1和2

之間的新住址列#ID是它類似於您的問題?你猜有些自動增量 - 與你的僵局有關嗎? 這些以下是可能的解決辦法...

  • 解決方法1 更改隔離級別? - >怎麼?!我沒有答案...而我不舒服,這將改變任何事情。

  • 解決方案2 將JPA實體ID生成策略(自動或標識)替換爲自定義序列表。

  • Solution3

檢查,如果你不能在多對一的關係使用級聯策略。

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; 

然後兩行保存到一個單一的合併():

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

返回的實例與退給你兩個新#ids插入,而魔術:不再僵局......

解決方案#3更智能,但需要更深入的分析並更改一些代碼...

2

Whenever you supply a DataSource,Hibernate將忽略hibernate.connection.isolation設置。

您需要改爲在DataSource級別設置隔離級別。大多數連接池或XA Java EE應用服務器數據源允許您設置全局事務隔離級別,因此來自該DataSource的所有連接都會繼承相同的隔離級別。