目录
前言
MyBatis作为Java语言的数据库框架,对数据库的事务管理是其非常重要的一个方面。
一、事务(Transaction)
1.什么是事务?
一个事物是一个完整的逻辑单元,不可再分。
比如:银行账户转账,从A账户向B账户转账10000,需要执行两条update语句
update t_act set balance = balance - 10000 where actno = 'act-001';
update t_act set balance = balance + 10000 where actno = 'act-002';
以上两条DML语句必须同时成功,或者同时失败,不允许出现一条成功,一条失败。
要想保证以上两条DML语句同时成功或者同时失败,那么就需要使用数据库的“事务机制”。
2.例子
在上图三条语句都要执行,执行之后:
提交:提交事务之后语句就会保存到文件中;
回滚:回滚事务后语句会有记录但不会保存到文件中。
事务的语句:
提交事务:COMMIT TRANSACTION(事务)
回滚事务:ROLLBACK TRANSACTION(事务)
3.事务的4个属性(ACID)
原子性(Atomic):事务是最小的工作单元,不可再分。
一致性(Consistency):事务必须保证多条DML语句同时成功或者同时失败。
隔离性(Isolation):事务允许多个用户对同一个数据进行并发访问,而不破坏数据的正确性和完整性。事务A与事务B之间具有隔离。
持久性(Durability):事务完成之后,它对于 系统的影响是永久的,该修改即使出现系统故障也将一直保留,真实的修改了数据库。
二、MyBatis的事务管理机制
1.两种机制形式
使用JDBC的事务管理机制:
即利用java.sql.Connection对象完成对事务的提交(commit())、回滚(rollback())、关闭(close())等。使用JDBC事务管理器,底层是通过JdbcTransaction对象创建事务管理器对象。
<transactionManager type="JDBC"/>
mybatis框架自己管理事务,自己采用原生的JDBC代码去管理事务:
conn.setAutoCommit(false); 开启事务
。。。业务处理。。。。
conn.commit(); 手动提交事务
如果没有在jdbc代码中执行:conn.setAutoCommit(flase);默认的autoCommit是true。
使用MANAGED的事务管理机制:
这种机制MyBatis自身不会去实现事务管理,而是让程序的容器如(JBOSS,Weblogic,spring)来实现对事务的管理
<transactionManager type="MANAGED"/>
重点:
只要autoCommit是true,就表示没有开启事务;只有当autoCommit是false的时候才表示开启了事务。
2.两种事务管理机制的创建和使用
2.1事务工厂的创建
MyBatis事务的创建是交给TransactionFactory 事务工厂来创建的,MyBatis对节点<transactionManager>的解析会生成TransactionFactory实例;如果type = "JDBC",则MyBatis会创建一个JdbcTransactionFactory.class 实例;如果type="MANAGED",则MyBatis会创建一个MangedTransactionFactory.class实例。
/**
* 解析<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.");
}
2.2事务Transaction的创建
通过事务工厂TransactionFactory很容易获取到Transaction对象实例。JdbcTransactionFactory会创建JDBC类型的Transaction,即JdbcTransaction。类似地,ManagedTransactionFactory也会创建ManagedTransaction。
JdbcTransaction:
JdbcTransaction直接使用JDBC的提交和回滚事务管理机制 。JdbcTransaction是使用的java.sql.Connection 上的commit和rollback功能,Transaction的事务管理都是通过java.sql.Connection实现的。
ManagedTranaction:
ManagedTransaction让容器来管理事务Transaction的整个生命周期,意思就是说,使用ManagedTransaction的commit和rollback功能不会对事务有任何的影响,它什么都不会做,它将事务管理的权利移交给了容器来实现。