事务对数据库的重要性,就不用多说了
我们先来看下mybatis中事务的隔离级别
public enum TransactionIsolationLevel {
//无
NONE(Connection.TRANSACTION_NONE),
// (读已提交):可避免脏读的发生READ_COMMITTED(Connection.TRANSACTION_READ_COMMITTED),
// (读未提交):最低级别,任何情况都无法保证
READ_UNCOMMITTED(Connection.TRANSACTION_READ_UNCOMMITTED),
// (可重复读):可避免脏读、不可重复读的发生REPEATABLE_READ(Connection.TRANSACTION_REPEATABLE_READ),
(串行化):可避免脏读、不可重复读、幻读的发生,但是性能低下
SERIALIZABLE(Connection.TRANSACTION_SERIALIZABLE);
}
如下是mybatis事务结构
结构看起来其实很简单,类图我就不画了 -_-!
可以看出,事务分两种,JdbcTransaction(JDBC)和ManagedTransaction(外部容器)
<environments default="development">
<environment id="development">
//决定事务的类型,例子中用的是JDBC
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl" />
<property name="username" value="**" />
<property name="password" value="**" />
</dataSource>
</environment>
</environments>
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)) {
TransactionFactory txFactory =
//根据transactionManager属性从typeAliasRegistry.resolveAlias中获取对应的工厂类 transactionManagerElement(child.evalNode("transactionManager"));
DataSourceFactory dsFactory = dataSourceElement(child.evalNode("dataSource"));
DataSource dataSource = dsFactory.getDataSource();
Environment.Builder environmentBuilder = new Environment.Builder(id)
.transactionFactory(txFactory)
.dataSource(dataSource);
configuration.setEnvironment(environmentBuilder.build());
}
}
}
}
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
try {
final Environment environment = configuration.getEnvironment();
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
//初始化事务实例,数据连接、事务等级、自动提交
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
final Executor executor = configuration.newExecutor(tx, execType);
return new DefaultSqlSession(configuration, executor, autoCommit);
} catch (Exception e) {
closeTransaction(tx); // may have fetched a connection so lets call close()
throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
好了,事务已经初始化完成!
public interface Transaction {
//获取连接
Connection getConnection() throws SQLException;
//提交
void commit() throws SQLException;
//回滚
void rollback() throws SQLException;
//关闭
void close() throws SQLException;
Integer getTimeout() throws SQLException;
对于JDBC和Manager来说,区别在于 Manager没有实现提交回滚,全部交由外部容器实现;ManagerFactory可以配置可以关闭一个连接connection!!