MyBatis事务
本篇主要学习MyBatis的事务代码,从设计模式,代码实现,事务分类等三个方面进行学习。关于数据库事务的特性和隔离级别与传播级别此处不做学习,将会有另外的篇幅进行学习。
事务分类
MyBatis事务分为两个类型,分别是JdbcTransaction和ManagedTransaction。开发过程中主要使用前者,按照type="jdbc" 或者type="managed" ,如不配置则会提示配置不完整。示例配置如下:
设计模式篇
两种事务类都是采用了工厂模式进行创建,JdbcTransaction的创建工厂是JdbcTransactionFactory,代码如下:
ManagedTransaction的创建工厂是ManagedTransactionFactory,代码如下:
而JdbcTransactionFactory和ManagedTransactionFactory都是实现了TransactionFactory接口,JdbcTransaction和ManagedTransaction都实现了Transaction接口,体现了设计原则中依赖倒转原则,即面向接口编程,依赖于抽象而不是具体。
代码实现篇
Transaction
JdbcTransaction
该事务实现类直接利用JDBC的提交和回滚功能,并依赖于从管理事务作用域的数据源中获取的connection,延迟连接的获取直到getConnection()方法执行的时候,当自动提交开启的时候会忽略提交和回滚请求。
类变量:
protected Connection connection;//数据库连接
protected DataSource dataSource;//数据源
protected TransactionIsolationLevel level;//事务隔离级别
// MEMO: We are aware of the typo. See #941
protected boolean autoCommmit;//自动提交标识
构造函数 :
虽然有两个构造函数,但是在创建事务的时候是通过事务工厂调用第一个构造函数创建事务
事务提交和回滚
关闭连接
关闭连接的时候重置了自动提交
此处注释值得注意:如果是查询操作,mybatis不会在一个连接上执行提交或者回滚。某些数据库在查询操作时会开启是数据库事务,并且在关闭连接前强制提交或者回滚。此时就是一个工作区,在关闭连接前设置自动提交为true。Sybase数据库此处会抛异常,也许是Sybase不允许设置自动提交,有待后续确认。
打开连接:
此处就是从数据源中获取连接,在隔离级别部位null的情况下设置隔离级别,然后设置是否自动提交。
事务隔离级别:TransactionIsolationLevel,是一个枚举类,共五个枚举值。
其中的level值就是jdbc的Connection中定义的int值,此处mybatis做了一个枚举类的封装。
事务使用
定义了事务后我们在哪里使用呢?请继续向下看
DefaultSqlSession中增删改查的操作最后都是调用Executor执行的,BaseExecutor作为Executor实现类的父类,实现了提交和回滚等方法,供子类公用。看看DefaultSqlSession的创建:new DefaultSqlSession(configuration, executor, autoCommit);
就知道它已经拥有了executor类。DefaultSqlSession的callback和commit 就是调用上述方法: