Mybatis学习笔记-事务管理详解
来源:互联网 发布:redis mysql同步 编辑:程序博客网 时间:2024/06/06 05:22
Mybatis作为最流行的持久层框架,当然支持事务的统一管理。
不多说,先来张图热热场…
该图大致概括了mybatis的事务体系。
mybatis事务的分类
1)JDBC :直接简单使用了JDBC 的提交和回滚设置。
2)MANAGED:这个配置几乎没做什么。它从来不提交或回滚一个连接,通常情况下,在mybatis与spring集成时这样设置,因为spring提供了同意的事务管理,mybatis在事务上不需要做任何事情。配置mybatis事务管理器
在mybatis核心配置文件中
<environments default="mysql_environment"> <environment id="mysql_environment"> <!-- 配置mybatis的事务 --> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver" /><property name="url" value="jdbc:mysql://localhost:3306/test" /> <property name="username" value="zhangdd" /> <property name="password" value="zd1991.." /> </dataSource> </environment></environments>
其中<transactionManager/>
节点指定了事务管理器的类型,该节点只有一个type属性。
- mybatis创建事务
应用启动时,mybatis会加载核心配置文件,当加载到<environments/>
节点时,会根据<transactionManager/>
和<dataSource>
来创建一个Environment对象:public Environment(String id, TransactionFactory transactionFactory, DataSource dataSource) {
,从这个构造器签名中我们可以看到,事务(Transaction)是由事务工厂(TransactionFactory)创建的。
创建事务与创建数据源类似,TransactionFactory是事务工程的顶级接口,其下有两个实现类:JdbcTransactionFactory
和ManagedTransactionFactory
,mybatis根据<transactionManager/>
的type属性来选择用哪种工厂类创建事务。
JDBC Transaction是创建如下:
JdbcTransactionFactory:
public class JdbcTransactionFactory implements TransactionFactory{public void setProperties(Properties props) {} public Transaction newTransaction(Connection conn) { return new JdbcTransaction(conn); } public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommit) { return new JdbcTransaction(ds, level, autoCommit); }}
JdbcTransaction:
public class JdbcTransaction implements Transaction { private static final Log log = LogFactory.getLog(JdbcTransaction.class); protected Connection connection; protected DataSource dataSource; protected TransactionIsolationLevel level; protected boolean autoCommmit; public JdbcTransaction(DataSource ds, TransactionIsolationLevel desiredLevel, boolean desiredAutoCommit) { dataSource = ds; level = desiredLevel; autoCommmit = desiredAutoCommit; } public JdbcTransaction(Connection connection) { this.connection = connection; } public Connection getConnection() throws SQLException { if (connection == null) { openConnection(); } return connection; } public void commit() throws SQLException { if (connection != null && !connection.getAutoCommit()) { if (log.isDebugEnabled()) { log.debug("Committing JDBC Connection [" + connection + "]"); } connection.commit(); } } public void rollback() throws SQLException { if (connection != null && !connection.getAutoCommit()) { if (log.isDebugEnabled()) { log.debug("Rolling back JDBC Connection [" + connection + "]"); } connection.rollback(); } } public void close() throws SQLException { if (connection != null) { resetAutoCommit(); if (log.isDebugEnabled()) { log.debug("Closing JDBC Connection [" + connection + "]"); } connection.close(); } } protected void setDesiredAutoCommit(boolean desiredAutoCommit) { try { if (connection.getAutoCommit() != desiredAutoCommit) { if (log.isDebugEnabled()) { log.debug("Setting autocommit to " + desiredAutoCommit + " on JDBC Connection [" + connection + "]"); } connection.setAutoCommit(desiredAutoCommit); } } catch (SQLException e) { throw new TransactionException("Error configuring AutoCommit. " + "Your driver may not support getAutoCommit() or setAutoCommit(). " + "Requested setting: " + desiredAutoCommit + ". Cause: " + e, e); } } protected void resetAutoCommit() { try { if (!connection.getAutoCommit()) { 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() throws SQLException { if (log.isDebugEnabled()) { log.debug("Openning JDBC Connection"); } connection = dataSource.getConnection(); if (level != null) { connection.setTransactionIsolation(level.getLevel()); } setDesiredAutoCommit(autoCommmit); }}
很显然,JdbcTransaction是通过底层的Connection对象来管理事务的。
ManagedTransactionFactory:
public class ManagedTransactionFactory implements TransactionFactory { private boolean closeConnection = true; public void setProperties(Properties props) { if (props != null) { String closeConnectionProperty = props.getProperty("closeConnection"); if (closeConnectionProperty != null) { closeConnection = Boolean.valueOf(closeConnectionProperty); } } } public Transaction newTransaction(Connection conn) { return new ManagedTransaction(conn, closeConnection); } public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommit) { return new ManagedTransaction(ds, level, closeConnection); }}
ManagedTransaction:
public class ManagedTransaction implements Transaction { private static final Log log = LogFactory.getLog(ManagedTransaction.class); private DataSource dataSource; private TransactionIsolationLevel level; private Connection connection; private boolean closeConnection; public ManagedTransaction(Connection connection, boolean closeConnection) { this.connection = connection; this.closeConnection = closeConnection; } public ManagedTransaction(DataSource ds, TransactionIsolationLevel level, boolean closeConnection) { this.dataSource = ds; this.level = level; this.closeConnection = closeConnection; } public Connection getConnection() throws SQLException { if (this.connection == null) { openConnection(); } return this.connection; } public void commit() throws SQLException { // Does nothing } public void rollback() throws SQLException { // Does nothing } public void close() throws SQLException { if (this.closeConnection && this.connection != null) { if (log.isDebugEnabled()) { log.debug("Closing JDBC Connection [" + this.connection + "]"); } this.connection.close(); } } protected void openConnection() throws SQLException { if (log.isDebugEnabled()) { log.debug("Openning JDBC Connection"); } this.connection = this.dataSource.getConnection(); if (this.level != null) { this.connection.setTransactionIsolation(this.level.getLevel()); } }}
从上面的代码中可以提炼出最重要的几行:
public void commit() throws SQLException { // Does nothing } public void rollback() throws SQLException { // Does nothing }
是的,就想你看到的那样,commit()
和rollback()
什么都没有做。
当将事务类型配置成Managed
时,mybatis所有的DML操作都将失效,事务会交由spring或web容器统一管理。
- Mybatis学习笔记-事务管理详解
- Spring事务管理学习笔记
- Spring学习笔记----事务管理
- Spring事务管理学习笔记
- Spring学习笔记 事务管理
- mybatis学习笔记(八)Sqlsession详解
- Mybatis事务管理
- MyBatis事务管理
- myBatis:事务管理
- Mybatis事务管理
- Mybatis事务管理
- spring学习笔记:spring事务管理
- spring学习笔记:spring事务管理
- spring学习笔记:spring事务管理
- Spring 的事务管理学习笔记
- hibernate学习笔记3--事务管理
- Spring框架学习笔记----事务管理
- Spring 学习笔记之事务管理
- [优先队列+贪心]poj3614 Sunscreen
- C# 获取当前路径方法
- 结构体的定义及其初始化方法And typedef的使用-----------权当笔记了
- [kuangbin带你飞]专题四 最短路练习
- 数据结构基础(22)--红黑树的设计与实现(上)
- Mybatis学习笔记-事务管理详解
- Android中inflate简介
- BFS
- 工作周记
- HDOJ 题目3065 病毒侵袭持续中(AC自动机,求字串在母串出现个数)
- 【翻译】在Ext JS 6通用应用程序中使用既共享又特定于视图的代码
- KMP算法 —— next 数组的应用 --- 前缀中最小循环节,最大重复次数
- BMP、JPEG、PNG、GIF格式总结
- vb.net SplitContainer控件增加自动拆分的小箭头