多个@Transactional无法正常工作

时间:2014-07-07 09:48:39

标签: java spring transactions

我正在使用 Spring 3.2.1 版本。我的应用程序中有两个单独的DataSource(2个DB),我们必须分别对它们运行声明式事务(不需要XA或JTA事务,因为它们永远不会在一个事务中一起使用)。

根据spring参考,我们可以有两个独立的事务管理器,在限定符的帮助下我们可以指向它们,但不幸的是在我的应用程序中只有一个有效。

以下是我面临的问题

1.Qualifier无法正常工作,即使我在注释中输入错误的跨国经理名称,即@Transactional(“someBadName”),春天也不会抱怨它。

2.我在spring上下文文件中有两个事务管理器。事务管理器包含优先级(包含在上下文中),是总是控制事务的事务管理器,而春天只是忽略了另一个事务管理器。

以下是配置文件

为了保持帖子简短,我只显示了上下文和java文件的相关部分。

事务管理器1(dataSourceA-Context.xml)

    <context:annotation-config />
    <bean id="txManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
        <qualifier value="**DATABASE_A**" />
    </bean>

    <bean id="driverManagerDataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource"
        lazy-init="true">
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.user}" />
        <property name="password" value="${jdbc.password}" />
    </bean>

    <bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close" lazy-init="true">
        <property name="driverClass" value="${jdbc.driver}" />
        <property name="jdbcUrl" value="${jdbc.url}" />
        <property name="user" value="${jdbc.user}" />
        <property name="password" value="${jdbc.password}" />
    </bean>

    <bean id="dataSource" parent="c3p0DataSource" />

    <bean id="simpleJdbcDaoSupport"
        class="org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport">
        <property name="dataSource" ref="dataSource" />
    </bean>

事务管理器2(dataSourceB-Context.xml)

<context:annotation-config />

<bean id="sMTxManager"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="sMDataSource" />
    <qualifier value="**DATABASE_B**" />
</bean>

<bean id="c3p0SmDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
    destroy-method="close" lazy-init="true">
    <property name="driverClass" value="${jdbc.servletmaster.driver}" />
    <property name="jdbcUrl" value="${jdbc.servletmaster.url}" />
    <property name="user" value="${jdbc.servletmaster.user}" />
    <property name="password" value="${jdbc.servletmaster.password}" />
</bean>

<bean id="sMDataSource" parent="c3p0SmDataSource" />

<bean id="sMSimpleJdbcDaoSupport"
    class="org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport">
    <property name="dataSource" ref="sMDataSource" />
</bean>

上下文文件,包括上面的事务管理器(context.xml)

<tx:annotation-driven mode="aspectj" />
<import resource="classpath:dataSourceA-context.xml" />
<import resource="classpath:dataSourceB-context.xml" />

Java服务bean:

服务后面有一个DAO层,它将数据插入到各自的数据库中。所有事务都是从服务层启动的.Below是服务类之一。

@Component
public class DualDBService{

  @Autowire
  private DatabaseADao dbA_Dao;

  @Autowire
  private DatabaseBDao dbB_Dao;

  @Transactional("DATABASE_A")
  public void createDataInDB_A(){
      dbA_Dao.insert("database A data");
      throw new RuntimeException("rollback in DB A");
  }

  @Transactional("DATABASE_B")
  public void createDataInDB_B(){
      dbB_Dao.insert("database B data");
      throw new RuntimeException("rollback in DB B");

  }

  @Transactional("SOME_BAD_NAME")
  public void badTransName_StillWorking(){
      dbB_Dao.insert("database B data");
      throw new RuntimeException("rollback in DB B");

  }

  // setter-getter for DAO's

}

观察

  1. 每当我调用createDataInDB_A时,事务永远不会回滚
  2. 每当我调用createDataInDB_B时,都会回滚事务。
  3. Spring从不抱怨@Transactional(“SOME_BAD_NAME”),即名字不好, 并且事务被回滚。事务管理器限定符无法正常工作。
  4. 如果我颠倒了所包含的事务管理器的顺序(第一个dataSourceB-Context.xml,然后是dataSourceA-Context.xml),那么行为也会反转,A的所有事情都会发生,B的停止会发生。
  5. 两个交易经理都不能共存只有其中一个有效或可能我做错了。我在Tomcat上测试这个Web应用程序。请帮忙!

0 个答案:

没有答案