MyBatis配合spring事務處理註解無效的問題
在使用ssm中遇到使用了Spring的@Transactional註解加註了方法或service後,mybatis還是自動提交併且無法回滾的問題。在排查了程式碼的配置後發現,問題出現的原因主要是由於不同bean的配置位置造成的。
解決方法主要時調整bean宣告的位置,主要思路如下:
(1)、資料庫相關的配置(datasource、service、dao、事物處理的管理類以及使用事務處理的方法)統一放到根ApplicationContext的配置中。
(2)、web mvc相關的配置統一放到servlet的配置中。
本例資料庫部分使用xml進行配置,ApplicationContext和DispatcherServlet使用基於java的配置。大致部分的原始碼如下:
1、mybatis的xml配置
mybatis在xml中進行配置,配置部分的程式碼如下:
<?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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
<!-- 自動掃描 -->
<context:component-scan base-package="api.landsem.mybatis.service.impl" />
<!-- 引入配置檔案 -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties" />
</bean>
<!-- dataSource configuration -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="minPoolSize" value="10" />
<property name="maxPoolSize" value="100" />
<property name="acquireIncrement" value="3" />
<property name="maxIdleTime" value="60" />
<property name="checkoutTimeout" value="18000" />
<property name="idleConnectionTestPeriod" value="180" />
</bean>
<!-- spring和MyBatis完美整合,不需要mybatis的配置對映檔案 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 自動掃描mapping.xml檔案 -->
<property name="mapperLocations" value="classpath:api/landsem/mybatis/mapping/*.xml" />
</bean>
<!-- DAO介面所在包名,Spring會自動查詢其下的類 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="api.landsem.mybatis.IDao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
<!-- transaction support -->
<!-- PlatformTransactionMnager -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- enable transaction annotation support -->
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
2、ApplicationContext配置
ApplicationContext的java配置類原始碼如下:
package api.landsem.base.configuration;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.support.ResourceBundleMessageSource;
import api.landsem.device.v1.configuration.DeviceApiV1RootConfiguration;
import api.landsem.iot.v1.configuration.IotApiV1RootConfiguration;
@Configuration
@ComponentScan({"api.landsem.base.bean"})
@ImportResource("classpath:applicationContext-*.xml")
@Import({DeviceApiV1RootConfiguration.class,IotApiV1RootConfiguration.class})
public class RootConfiguration {
@Bean("messageSource")
public MessageSource getResourceBundleMessageSourc() {
ResourceBundleMessageSource resource = new ResourceBundleMessageSource();
resource.setBasename("i18n/i18n");
return resource;
}
}
3、DispatcherServlet配置
DispatcherServlet的java配置類原始碼如下:
package api.landsem.base.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import api.landsem.base.interceptor.LoggerInterceptor;
import api.landsem.device.v1.configuration.DeviceApiV1WebMvcConfiguration;
import api.landsem.iot.v1.configuration.IotApiV1WebMvcConfiguration;
@Configuration
@EnableWebMvc
@Import({DeviceApiV1WebMvcConfiguration.class,IotApiV1WebMvcConfiguration.class})
public class DefaultWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter{
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
registry.addResourceHandler("/static/**","/css/**");
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
this.addLogInterceptors(registry);
super.addInterceptors(registry);
}
/**
* @Title: addLogInterceptors
* @Description: Add log interceptor to record request information.
* @param registry
*/
private void addLogInterceptors(InterceptorRegistry registry) {
InterceptorRegistration reg = registry.addInterceptor(new LoggerInterceptor());
if(null != reg) {
reg.addPathPatterns("/base/**","/wechat/**");
}
}
}
相關文章
- 【Spring註解】事務註解@TransactionalSpring
- Spring事務專題(三)事務的基本概念,Mysql事務處理原理SpringMySql
- Spring是如何處理註解的Spring
- 日期格式化時註解@DateTimeFormat無效的問題分析ORM
- ORACLE懸疑分散式事務問題處理Oracle分散式
- Spring Cloud Finchley版中Consul多例項註冊的問題處理SpringCloud
- Springboot資料庫事務處理——Spring宣告式事務Spring Boot資料庫
- Spring多執行緒事務處理Spring執行緒
- 問題:mybatis like 佔位符處理MyBatis
- 《四 spring原始碼》spring的事務註解@Transactional 原理分析Spring原始碼
- spring事務管理原始碼分析(二)事務處理流程分析Spring原始碼
- SQLServer 2008中事務日誌已滿問題處理SQLServer
- Spring事務的介紹,以及基於註解@Transactional的宣告式事務Spring
- Spring Boot 整合 Seata 解決分散式事務問題Spring Boot分散式
- Spring非同步Async和事務Transactional註解Spring非同步
- 分散式事務處理方案,微服事務處理方案分散式
- lombok 註解無效 已解決Lombok
- Spring+Mybatis事務@Transactional註解timeout屬性作用過程原始碼淺層DebugSpringMyBatis原始碼
- spring boot 註解物件的問題 待研究Spring Boot物件
- spring基於註解配置實現事務控制Spring
- mysqli 事務處理MySql
- MySQL事務處理MySql
- springboot事務處理Spring Boot
- SpringBoot 配置CORS處理前後端分離跨域配置無效問題解析Spring BootCORS後端跨域
- mybatis plus框架的@TableField註解不生效問題總結MyBatis框架
- 使用Seata徹底解決Spring Cloud中的分散式事務問題!SpringCloud分散式
- Spring基礎系列-Spring事務不生效的問題與迴圈依賴問題Spring
- Spring事務(Transaction)管理高階篇一棧式解決開發中遇到的事務問題Spring
- 註解處理器
- 自然語言處理之序列標註問題自然語言處理
- 如何處理快取導致的無效曝光快取
- 解決mysqld_multi stop命令無效問題MySql
- 專案中Spring事務失效的場景問題排查Spring
- 處理 HTTP 請求的註解HTTP
- .NET開源的處理分散式事務的解決方案分散式
- Spring事務專題(四)Spring中事務的使用、抽象機制及模擬Spring事務實現Spring抽象
- Laravel 分散式事務處理Laravel分散式
- 事務處理基本概念
- MyBatis中的事務MyBatis