《深入理解mybatis原理》 MyBatis事务管理机制

MyBatis作为Java语言的数据库框架,对数据库的事务管理是其非常重要的一个方面。本文将讲述MyBatis的事务管理的实现机制。首先介绍MyBatis的事务Transaction的接口设计以及其不同实现JdbcTransaction和 ManagedTransaction;接着,从MyBatis的XML配置文件入手,讲解MyBatis事务工厂的创建和维护,进而阐述了MyBatis事务的创建和使用;最后分析JdbcTransaction和ManagedTransaction的实现和二者的不同特点。

以下是本文的组织结构:

一、概述

对数据库的事务而言,应该具有以下几点:创建(create)、提交(commit)、回滚(rollback)、关闭(close)。对应地,MyBatis将事务抽象成了Transaction接口:其接口定义如下:

MyBatis的事务管理分为两种形式:

一、使用JDBC的事务管理机制:即利用java.sql.Connection对象完成对事务的提交(commit())、回滚(rollback())、关闭(close())等

二、使用MANAGED的事务管理机制:这种机制MyBatis自身不会去实现事务管理,而是让程序的容器如(JBOSS,Weblogic)来实现对事务的管理

这两者的类图如下所示:

二、事务的配置、创建和使用1. 事务的配置

我们在使用MyBatis时,一般会在MyBatisXML配置文件中定义类似如下的信息:

<environment>节点定义了连接某个数据库的信息,其子节点<transactionManager> 的type 会决定我们用什么类型的事务管理机制。

2.事务工厂的创建

MyBatis事务的创建是交给TransactionFactory 事务工厂来创建的,如果我们将<transactionManager>的type 配置为"JDBC",那么,在MyBatis初始化解析<environment>节点时,会根据type="JDBC"创建一个JdbcTransactionFactory工厂,其源码如下:

/*** 解析<transactionManager>节点,创建对应的TransactionFactory* @param context* @return* @throws Exception*/ private TransactionFactory transactionManagerElement(XNode context) throws Exception {if (context != null) {String type = context.getStringAttribute("type");Properties props = context.getChildrenAsProperties();/*在Configuration初始化的时候,会通过以下语句,给JDBC和MANAGED对应的工厂类typeAliasRegistry.registerAlias("JDBC", JdbcTransactionFactory.class);typeAliasRegistry.registerAlias("MANAGED", ManagedTransactionFactory.class);下述的resolveClass(type).newInstance()会创建对应的工厂实例*/TransactionFactory factory = (TransactionFactory) resolveClass(type).newInstance();factory.setProperties(props);return factory;}throw new BuilderException("Environment declaration requires a TransactionFactory."); } 如上述代码所示,如果type = "JDBC",则MyBatis会创建一个JdbcTransactionFactory.class 实例;如果type="MANAGED",则MyBatis会创建一个MangedTransactionFactory.class实例。

MyBatis对<transactionManager>节点的解析会生成 TransactionFactory实例;而对<dataSource>解析会生成datasouce实例(关于dataSource的解析和原理,读者可以参照我的另一篇博文:《深入理解mybatis原理》 Mybatis数据源与连接池 ),作为<environment>节点,会根据TransactionFactory和DataSource实例创建一个Environment对象,代码如下所示:

private void environmentsElement(XNode context) throws Exception {if (context != null) {if (environment == null) {environment = context.getStringAttribute("default");}for (XNode child : context.getChildren()) {String id = child.getStringAttribute("id");//是和默认的环境相同时,解析之if (isSpecifiedEnvironment(id)) {//1.解析<transactionManager>节点,决定创建什么类型的TransactionFactoryTransactionFactory txFactory = transactionManagerElement(child.evalNode("transactionManager"));//2. 创建dataSourceDataSourceFactory dsFactory = dataSourceElement(child.evalNode("dataSource"));DataSource dataSource = dsFactory.getDataSource();//3. 使用了Environment内置的构造器Builder,传递id 事务工厂TransactionFactory和数据源DataSourceEnvironment.Builder environmentBuilder = new Environment.Builder(id).transactionFactory(txFactory).dataSource(dataSource);configuration.setEnvironment(environmentBuilder.build());}}} } Environment表示着一个数据库的连接,生成后的Environment对象会被设置到Configuration实例中,以供后续的使用。

上述一直在讲事务工厂TransactionFactory来创建的Transaction,现在让我们看一下MyBatis中的TransactionFactory的定义吧。

3. 事务工厂TransactionFactory

事务工厂Transaction定义了创建Transaction的两个方法:一个是通过指定的Connection对象创建Transaction,,另外是通过数据源DataSource来创建Transaction。与JDBC 和MANAGED两种Transaction相对应,TransactionFactory有两个对应的实现的子类:如下所示:

4. 事务Transaction的创建没有什么可凭仗,只有他的好身体,没有地方可去,只想到处流浪。

《深入理解mybatis原理》 MyBatis事务管理机制

相关文章:

你感兴趣的文章:

标签云: