因为需要对两个数据库同时操作并且放在同一个事务中,所以采用了atomikos去实现JTA分布式事务。数据库用的是SQL Server2014 .
现在的问题是,事务提交回滚,一切都正常,但是没有按照设定好的事务隔离级别给数据库表加锁。比如service中的save方法 设定的是SERIALIZABLE隔离级别,测试时查询数据库表隔离级别,并未按照预期加锁。
以下是配置文件,请大神给解惑一下。
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<!-- 修改 -->
<!-- 1.扫描包 -->
<!--context:component-scan base-package=""></context:component-scan-->
<!--context:component-scan base-package="wms.*">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan-->
<context:component-scan base-package="com.baoJian.wmsBasic.*.dao">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context:component-scan>
<context:component-scan base-package="com.baoJian.wmsBasic.*.service">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
</context:component-scan>
<!-- 2.加载属性文件 -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties"></property>
</bean>
<!--develop开发环境配置,测试环境配置 对应web.xml中也有相关设置-->
<!--beans profile="develop">
<context:property-placeholder location="classpath:jdbc.properties"/>
</beans>
<beans profile="product">
<context:property-placeholder location="classpath:jdbc_product.properties"/>
</beans-->
<beans>
<!-- 修改 -->
<!-- 3.配置数据库连接池 更改为JTA-->
<bean class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close" id="dataSource">
<!-- Set unique name for this DataSource -->
<property name="uniqueResourceName"><value>dataSource_main</value></property>
<!-- Set XADatasource class name -->
<property name="xaDataSourceClassName" value="com.microsoft.sqlserver.jdbc.SQLServerXADataSource" />
<property name="xaProperties">
<props>
<prop key="URL">${jdbcUrl}</prop>
</props>
</property>
<!-- set properties for datasource connection pool -->
<property name="poolSize" value="3" />
<!-- timeout after 20000 seconds -->
<property name="minPoolSize" value="3" />
<property name="maxPoolSize" value="6" />
<property name="borrowConnectionTimeout" value="60" />
<property name="reapTimeout"><value>300</value></property>
<property name="loginTimeout" value="40" />
<property name="testQuery">
<value>select 1</value>
</property>
</bean>
<bean class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close" id="dataSource_erp">
<!-- Set unique name for this DataSource -->
<property name="uniqueResourceName"><value>dataSource_erp</value></property>
<!-- Set XADatasource class name -->
<property name="xaDataSourceClassName" value="oracle.jdbc.xa.client.OracleXADataSource" />
<property name="xaProperties">
<props>
<!--prop key="URL">jdbc:oracle:thin:@erptest.baojian.com:1541:DEV2</prop-->
<prop key="URL">${oraJdbcUrl}</prop>
<prop key="user">${oraUser}</prop>
<prop key="password">${oraPassword}</prop>
</props>
</property>
<!-- set properties for datasource connection pool -->
<property name="poolSize" value="3" />
<!-- timeout after 20000 seconds -->
<property name="reapTimeout"><value>300</value></property>
</bean>
<!-- 修改 -->
<!-- 4.Hibernate的相关信息 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:hibernate.cfg.xml"/>
</bean>
<bean id="sessionFactory_erp" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource_erp"></property>
<property name="configLocation" value="classpath:hibernate_erp.cfg.xml"/>
</bean>
<!-- 分布式事务 -->
<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close">
<property name="forceShutdown" value="true"/>
</bean>
<bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
<property name="transactionTimeout" value="50000"/>
</bean>
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="atomikosTransactionManager"/>
<property name="userTransaction" ref="atomikosUserTransaction"/>
<property name="allowCustomIsolationLevels" value="true"/>
</bean>
<!--<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean> -->
<!-- 6.开启事务注解 -->
<!--tx:annotation-driven transaction-manager="transactionManager"/-->
<tx:advice id="txAdvice" transaction-manager="transactionManager" >
<tx:attributes>
<!--init初始化操作 calculate计算类操作 save保存操作 remove删除操作 update更新操作-->
<tx:method name="init*" propagation="REQUIRED" rollback-for="Exception"></tx:method>
<tx:method name="calculate*" propagation="REQUIRED" rollback-for="Exception"></tx:method>
<tx:method name="save*" propagation="REQUIRED" isolation="SERIALIZABLE" rollback-for="Exception"></tx:method>
<tx:method name="*" read-only="true"></tx:method>
</tx:attributes>
</tx:advice>
<!--定义哪些类的哪些方法参与事务 -->
<aop:config>
<!-- <aop:pointcut id="allManagerMethod" expression="execution(* com.baojian.demo.service.*.*(..))"/> -->
<aop:pointcut id="allServiceMethod" expression="execution(* *..service.*.*(..))"/>
<aop:advisor pointcut-ref="allServiceMethod" advice-ref="txAdvice"/>
</aop:config>
</beans>
测试例子
server中的一个方法
public void saveTestHeader() throws InventoryServiceException, ReceiptServiceException
{
System.out.println("------------------TransactionSynchronizationManager"+TransactionSynchronizationManager.getCurrentTransactionIsolationLevel());
//查询并锁定
TestHeader testHeader = this.testDao.findOneByHQL("from TestHeader where id=160");
Thread.sleep(30000);
}