MyBatis源码阅读——MyBatis对事务的处理过程分析

2022-10-24 10:17:37

事务管理器

在 MyBatis 中有两种类型的事务管理器(也就是 type=”[JDBC|MANAGED]”):

 <environments default="development">
        <environment id="development">
            <!-- 配置事务管理器 -->
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://127.0.0.1/learn?useUnicode=true&amp;characterEncoding=utf-8"/>
                <property name="username" value="root"/>
                <property name="password" value="12345"/>
            </dataSource>
        </environment>
    </environments>

* JDBC – 这个配置就是直接使用了 JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域。即利用java.sql.Connection对象完成对事务的提交(commit())、回滚(rollback())、关闭(close())等
* MANAGED – 这个配置几乎没做什么。它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。 默认情况下它会关闭连接,然而一些容器并不希望这样,因此需要将 closeConnection 属性设置为 false 来阻止它默认的关闭行为。这种机制MyBatis自身不会去实现事务管理,而是让程序的容器如(JBOSS,Weblogic)来实现对事务的管理。

    < transactionManager type="MANAGED">
        < property name="closeConnection" value="false"/>
    </ transactionManager>

如果你正在使用 Spring + MyBatis,则没有必要配置事务管理器, 因为 Spring 模块会使用自带的管理器来覆盖前面的配置。

这里写图片描述
这两种事务管理器类型都不需要任何属性。它们不过是类型别名,换句话说,你可以使用 TransactionFactory 接口的实现类的完全限定名或类型别名代替它们。

事务使用

JdbcTransaction

JdbcTransaction由TransactionFactory->openSessionFromConnection()方法生成
这里写图片描述
这里写图片描述
从JdbcTransaction的源码中,你应该可以看出,JdbcTransaction主要是对java.sql.Connection事务处理中的事务进行了一层封装。

ManagedTransaction

这里写图片描述
在ManagedTransaction源码中,commit,rollback方法全是空的,它让容器管理事务transaction的整个生命周期。也就是说,ManagedTransaction不会帮我们commit和rollback。
运行一段代码看下效果:

String resource = "mybatis/conf/mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //从 XML 中构建 SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = sqlSessionFactory.openSession(false);

        Blog blog = new Blog();
        blog.setBlogTitle("这是标题1");
        blog.setBlogContent("这是内容2");
        blog.setCreateTime(new Date());

        try {
            BlogMapper mapper = session.getMapper(BlogMapper.class);
            mapper.insert(blog);
            session.commit();
        }catch (Exception e){
            //手动回滚
            session.rollback();
        }finally {
            session.close();
        }

在我们未打开自动提交的情况下(事务必须关闭)它都是执行的空操作。不会影响数据库。

SpringManagedTransaction

在mybatis-spring jar包中,在SqlSession执行sql时通过用SpringManagedTransaction代替mybatis的JdbcTransaction,让SqlSession从spring的ThreadLocal中获取jdbc connection。关于Spring的事务处理原理可以看下此篇博客:https://blog.csdn.net/qq_18860653/article/details/80049281

参考文档

http://www.mybatis.org/mybatis-3/zh/configuration.html

  • 作者:爆裂码手
  • 原文链接:https://yuyufeng.blog.csdn.net/article/details/80680748
    更新时间:2022-10-24 10:17:37