在 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 多数据源的配置和管理



Spring 多数据源 @Transactional 注解事务管理的更多相关文章

  1. Spring Boot学习笔记(七)多数据源下的事务管理

    DataBaseConfig中加入事务管理器 DataBaseConfig的详解以及多数据源的配置参见我的上一篇文章 @Configuration @MapperScan(basePackages={ ...

  2. spring@Transactional注解事务不回滚不起作用无效的问题处理

    这几天在项目里面发现我使用@Transactional注解事务之后,抛了异常居然不回滚.后来终于找到了原因. 如果你也出现了这种情况,可以从下面开始排查. 一.特性先来了解一下@Transaction ...

  3. Spring 简单而强大的事务管理功能

    开始之前 关于本教程 本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本 ...

  4. @Transactional注解事务不回滚不起作用无效

     写在前面 数据库Mysql8.0 添加@Transactional注解后事务并未起作用. 修改表的引擎后ok了.(详看下面转载内容) ================================ ...

  5. [转]使用spring中的@Transactional注解时,可能需要注意的地方

    前情提要 在编写业务层方法时,会遇到很多需要事务提交的操作,spring框架为我们提供很方便的做法,就是在需要事务提交的方法上添加@Transactional注解,比起我们自己开启事务.提交以及控制回 ...

  6. 使用spring中的@Transactional注解时,可能需要注意的地方

    前情提要 在编写业务层方法时,会遇到很多需要事务提交的操作,spring框架为我们提供很方便的做法,就是在需要事务提交的方法上添加@Transactional注解,比起我们自己开启事务.提交以及控制回 ...

  7. spring boot配置mybatis和事务管理

    spring boot配置mybatis和事务管理 一.spring boot与mybatis的配置 1.首先,spring boot 配置mybatis需要的全部依赖如下: <!-- Spri ...

  8. Spring下面的@Transactional注解的讲解

    摘自: https://www.cnblogs.com/xiohao/p/4808088.html Spring下面的@Transactional注解标志的讲解 最近在开发中对Spring中的事务标记 ...

  9. Spring—SSJ集成&声明式事务管理

    1.   课程介绍 1.  SSJ集成;(掌握) 2.  声明式事务管理;(掌握) 什么是三大框架 2.1.  ssh Struts/Struts2 Spring Hibernate 2.2.  ss ...

随机推荐

  1. 为phpStorm 配置PHP_CodeSniffer自动检查代码

    通过composer 安装PHP_CodeSniffer : squizlabs/PHP_CodeSniffer gihub地址 composer global require "squiz ...

  2. php的大小写敏感问题整理

    php的大小写敏感问题整理 今天在开发php的过程中,因为命名大小写的问题导致代码错误,所以从网上整理了php的大小写敏感的一些资料,需要的朋友可以参考下.   PHP对大小写敏感问题的处理比较乱,写 ...

  3. Thunder团队第七周 - Scrum会议1

    Scrum会议1 小组名称:Thunder 项目名称:i阅app Scrum Master:杨梓瑞 工作照片: 参会成员: 王航:http://www.cnblogs.com/wangh013/ 李传 ...

  4. 《JavaScript》页面跳转

    window.location.href: <i onclick="window.location.href = '/Form/Form_Write/Index?viewname=Fo ...

  5. android入门 — Activity生命周期

    Activity总共有7个回调方法,代表着不同的生命周期的环节. 1.onCreate() 在活动第一次被创建的时候调用.在这个方法中需要完成活动的初始化操作,比如说加载布局.绑定事件等. 2.onS ...

  6. Java单例模式&static成员变量 区别

    当需要共享的变量很多时,使用static变量占用内存的时间过长,在类的整个生命周期. 而对象只是存在于对象的整个生命周期.   //饿汉式 class Single//类一加载,对象就已经存在了. { ...

  7. jQuery之回到顶部

    实现回到顶部的功能,根据学了元素滚动实现,温习知识点. 做之前先理清一下步骤和思路: 1.获得页面的滚动长度 var $page = $("html,body"); var dis ...

  8. Week2-作业1 -阅读《构建之法》

    第一章 在阅读第1.2.2节时,感受最深,记得开学初有老师就给我们分析过计算机专业和我们专业的区别,当时是给我们讲的是计算机科学注重的是理论,偏向于硬件方面,而软件工程则注重实践,偏向于软件方面.然很 ...

  9. [ Selenium2 从零开始 by Bruce from http://seleniumcn.cn ] 1-8 视频集锦

    内容转自: http://blog.csdn.net/sxl0727tu/article/details/51887093\ ************************************* ...

  10. webgl 初识2

    之前的文章介绍了webgl. 这里进一步精简. WebGL的全部内容就是创建不同的着色器, 向着色器提供数据然后调用gl.drawArrays 或 gl.drawElements 让WebGL调用当前 ...