mybatis没有事务管理的能力_mybatis事务管理机制详解

1.mybatis事务的配置和使用

mybatis事务有两种使用方式:

(a):使用JDBC的事务管理机制:即使用java.Sql.Connection对象完成对事务的提交,回滚和关闭操作。

(b):使用MANAGED的事务管理机制:mybatis本身不会去实现事务管理的相关操作,而是交个外部容器来管理事务。当与spring整合使用后,一般使用spring来管理事务。

在配置文件中的配置:

//JDBC的事务方式

在这段配置信息中,有三个节点:,,。其中,节点封装了数据源的信息,封装了数据库的连接,包括数据源和事务,然后把该节点信息封装到了Configuration对象中,方便后面使用,现在看下mybatis在初始化加载配置文件时,对节点的解析:

private void environmentsElement(XNode context) throwsException {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= transactionManagerElement(child.evalNode("transactionManager"));

// 解析节点,获取数据源对象

DataSourceFactory dsFactory= dataSourceElement(child.evalNode("dataSource"));

DataSource dataSource=dsFactory.getDataSource();

Environment.Builder environmentBuilder= newEnvironment.Builder(id)

.transactionFactory(txFactory)

.dataSource(dataSource);

configuration.setEnvironment(environmentBuilder.build());

}

}

}

}

进入解析节点的方法:

private TransactionFactory transactionManagerElement(XNode context) throwsException {if (context != null) {

// 获取type的属性值,JDBC或者MANAGED

String type= context.getStringAttribute("type");

Properties props=context.getChildrenAsProperties();

//生成一个TransactionFactory实例

TransactionFactory factory=(TransactionFactory) resolveClass(type).newInstance();

factory.setProperties(props);returnfactory;

}throw new BuilderException("Environment declaration requires a TransactionFactory.");

}

2.事务工厂TransactionFactory

TransactionFactory定义了创建Transaction的两种方法,如下:

public interfaceTransactionFactory {/*** Sets transaction factory custom properties.

*@paramprops*/

voidsetProperties(Properties props);/*** Creates a {@linkTransaction} out of an existing connection.

*@paramconn Existing database connection

*@returnTransaction

*@since3.1.0

* 方法一:通过指定的Connection对象来创建事务*/Transaction newTransaction(Connection conn);/*** Creates a {@linkTransaction} out of a datasource.

*@paramdataSource DataSource to take the connection from

*@paramlevel Desired isolation level

*@paramautoCommit Desired autocommit

*@returnTransaction

*@since3.1.0

* 方法二:通过DataSource,隔离级别,是否自动提交 来创建事务*/Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level,booleanautoCommit);

}

TransactionFactory有两个子类:JdbcTransactionFactory和ManagedTransactionFactory

2.1JdbcTransactionFactory,会创建JDBC类型的事务,就是JdbcTransaction,看下源码:

public class JdbcTransactionFactory implementsTransactionFactory {public voidsetProperties(Properties props) {

}

// JDBCTransaction的创建有两种方法publicTransaction newTransaction(Connection conn) {return newJdbcTransaction(conn);

}public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, booleanautoCommit) {return newJdbcTransaction(ds, level, autoCommit);

}

}

2.2 ManagedTransactionFactory,会创建MANAGED类型的事务,ManagedTransaction,同样有两种方法:

public class ManagedTransactionFactory implementsTransactionFactory {private boolean closeConnection = true;public voidsetProperties(Properties props) {if (props != null) {

String closeConnectionProperty= props.getProperty("closeConnection");if (closeConnectionProperty != null) {

closeConnection=Boolean.valueOf(closeConnectionProperty);

}

}

}publicTransaction newTransaction(Connection conn) {return newManagedTransaction(conn, closeConnection);

}public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, booleanautoCommit) {//Silently ignores autocommit and isolation level, as managed transactions are entirely//controlled by an external manager. It's silently ignored so that//code remains portable between managed and unmanaged configurations.

return newManagedTransaction(ds, level, closeConnection);

}

}

3.JdbcTransaction和ManagedTransaction

3.1 JdbcTransaction

从源码可知:jdbcTransaction从DataSource获取连接对象Connection,然后利用Connection对象管理事务的commit和rollback,实际在事务处理上,jdbcTransaction是对java.sql.Connection的一个包装,它是使用Connection对象来管理事务的。

public class JdbcTransaction implementsTransaction {private static final Log log = LogFactory.getLog(JdbcTransaction.class);protectedConnection connection;// 连接对象protectedDataSource dataSource; //数据源protectedTransactionIsolationLevel level; // 隔离级别protected booleanautoCommmit;//是否自动提交public JdbcTransaction(DataSource ds, TransactionIsolationLevel desiredLevel, booleandesiredAutoCommit) {

dataSource=ds;

level=desiredLevel;

autoCommmit=desiredAutoCommit;

}publicJdbcTransaction(Connection connection) {this.connection =connection;

}

// 获取连接对象public Connection getConnection() throwsSQLException {if (connection == null) {

openConnection();

}returnconnection;

}

// 使用Connection对象提交public void commit() throwsSQLException {if (connection != null && !connection.getAutoCommit()) {if(log.isDebugEnabled()) {

log.debug("Committing JDBC Connection [" + connection + "]");

}

connection.commit();

}

}public void rollback() throwsSQLException {if (connection != null && !connection.getAutoCommit()) {if(log.isDebugEnabled()) {

log.debug("Rolling back JDBC Connection [" + connection + "]");

}

connection.rollback();

}

}public void close() throwsSQLException {if (connection != null) {

resetAutoCommit();if(log.isDebugEnabled()) {

log.debug("Closing JDBC Connection [" + connection + "]");

}

connection.close();

}

}protected void setDesiredAutoCommit(booleandesiredAutoCommit) {try{if (connection.getAutoCommit() !=desiredAutoCommit) {if(log.isDebugEnabled()) {

log.debug("Setting autocommit to " + desiredAutoCommit + " on JDBC Connection [" + connection + "]");

}

connection.setAutoCommit(desiredAutoCommit);

}

}catch(SQLException e) {//Only a very poorly implemented driver would fail here,//and there's not much we can do about that.

throw new TransactionException("Error configuring AutoCommit. "

+ "Your driver may not support getAutoCommit() or setAutoCommit(). "

+ "Requested setting: " + desiredAutoCommit + ". Cause: " +e, e);

}

}protected voidresetAutoCommit() {try{if (!connection.getAutoCommit()) {//MyBatis does not call commit/rollback on a connection if just selects were performed.//Some databases start transactions with select statements//and they mandate a commit/rollback before closing the connection.//A workaround is setting the autocommit to true before closing the connection.//Sybase throws an exception here.

if(log.isDebugEnabled()) {

log.debug("Resetting autocommit to true on JDBC Connection [" + connection + "]");

}

connection.setAutoCommit(true);

}

}catch(SQLException e) {

log.debug("Error resetting autocommit to true "

+ "before closing the connection. Cause: " +e);

}

}protected void openConnection() throwsSQLException {if(log.isDebugEnabled()) {

log.debug("Opening JDBC Connection");

}

// 从数据源获取连接对象

connection=dataSource.getConnection();if (level != null) {

connection.setTransactionIsolation(level.getLevel());

}

setDesiredAutoCommit(autoCommmit);

}

}

3.2 ManagedTransaction

ManagedTransaction对事务的commit和rollback交给了容器去管理,自己本身并没有做任何处理,看源码:

public class ManagedTransaction implementsTransaction {private static final Log log = LogFactory.getLog(ManagedTransaction.class);privateDataSource dataSource;privateTransactionIsolationLevel level;privateConnection connection;private booleancloseConnection;public Connection getConnection() throwsSQLException {if (this.connection == null) {

openConnection();

}return this.connection;

}

// 没有做任何处理,因为交给了外部容器去做这件事了public void commit() throwsSQLException {//Does nothing

}public void rollback() throwsSQLException {//Does nothing

}public void close() throwsSQLException {if (this.closeConnection && this.connection != null) {if(log.isDebugEnabled()) {

log.debug("Closing JDBC Connection [" + this.connection + "]");

}this.connection.close();

}

}protected void openConnection() throwsSQLException {if(log.isDebugEnabled()) {

log.debug("Opening JDBC Connection");

}this.connection = this.dataSource.getConnection();if (this.level != null) {this.connection.setTransactionIsolation(this.level.getLevel());

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值