1. 程式人生 > >Spring 多資料來源 @Transactional 註解事務管理

Spring 多資料來源 @Transactional 註解事務管理

在 Spring,MyBatis 下兩個資料來源,通過 @Transactional 註解 配置簡單的事務管理

spring-mybatis.xml

<!--******************************** data one start ***************************************************************-->
<!-- 資料庫連線池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" 
init-method="init" destroy-method="close"> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <property
name="initialSize" value="10" /> <property name="minIdle" value="50" /> <property name="maxActive" value="100" /> <property name="maxWait" value="60000" /> <property name="useUnfairLock" value="true" /> <property name="timeBetweenEvictionRunsMillis" value="300000" /> <property
name="minEvictableIdleTimeMillis" value="600000" /> <property name="validationQuery" value="select 1" /> <property name="testWhileIdle" value="true" /> <property name="testOnBorrow" value="true" /> <property name="poolPreparedStatements" value="true" /> <property name="maxOpenPreparedStatements" value="200" /> <property name="maxPoolPreparedStatementPerConnectionSize" value="20" /> </bean> <!-- 讓spring管理sqlsessionfactory 使用mybatis和spring整合包中的 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 資料庫連線池 --> <property name="dataSource" ref="dataSource" /> <!-- 載入mybatis的全域性配置檔案 --> <property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml" /> <!-- 自動掃描mapping.xml檔案 --> <property name="mapperLocations" value="classpath:mybatis/mapping/*.xml" /> </bean> <!-- DAO介面所在包名,Spring會自動查詢其下的類 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.***.***.dao" /> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /> </bean> <!-- 設定transactionManager --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 支援 @Transactional 標記 --> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" /> <!--******************************** data one end ***************************************************************--> <!--******************************** data two start ***************************************************************--> <!-- 資料庫連線池 --> <bean id="dataSourceTwo" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <!--略寫--> </bean> <!-- 讓spring管理sqlsessionfactory 使用mybatis和spring整合包中的 --> <bean id="sqlSessionFactoryTwo" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSourceTwo" /> <!--略寫--> </bean> <!-- DAO介面所在包名,Spring會自動查詢其下的類 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!--略寫--> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryTwo" /> </bean> <!-- 設定transactionManager --> <bean id="transactionManagerTwo" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSourceTwo" /> </bean> <!-- 支援 @Transactional 標記 --> <tx:annotation-driven transaction-manager="transactionManagerTwo" proxy-target-class="true" /> <!--******************************** data two end 略寫 ***************************************************************-->

上面配置了兩個資料來源(dataSource,dataSourceTwo),兩個事務管理器(transactionManager,transactionManagerTwo)

@Transactional 事務註解

1)第一個資料來源,使用第一個事務管理器

@Override
@Transactional(value = "transactionManager",readOnly = false)
public void insert {
}

2)第二個資料來源,使用第二個事務管理器

@Override
@Transactional(value = "transactionManagerTwo",readOnly = false)
public void insert {
}

3)不使用 value 或者 @Transactional 標記,會使用 哪個資料來源 及起哪個事務?

@Override
@Transactional
public void insert {
}
@Override
public void insert {
}
像這種不標明的情況,會使用預設 事務管理器(transactionManager),所以只有一個事務管理器的時候,我們一般不寫 value


引出:一條SQL語句是否需要事務

事務的存在意義:當我們在執行資料庫操作時,例如:insert,update,delete  ,當發生錯誤導致執行失敗時,我們需要對整個操作進行回滾。

當我們只有一個操作如 insert,我們是不需要搞個事務跟蹤的, 因為一條語句就是一個事務,它自己本身就已經有事務了!!!

就算這條 insert 語句執行失敗,它自然不會插入成功,同時也不會對其它操作造成影響。

按我理解,事務應該用在執行多條語句,並且語句之間會相互影響的時候才需要,事務是用在多個語句保證同時成功的時候用,單個語句不建議用


需要注意的是,多個數據庫的這種配置是不支援分散式事務的,也就是同一個事務中,不能操作多個數據庫。

如果要實現分散式事務可參考:

Spring分散式事務實現

spring多資料來源配置

Spring, MyBatis 多資料來源的配置和管理

 關注公眾號,分享乾貨,討論技術