2010-07-21 59 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的所有连接都会继承相同的隔离级别。