在Ibatis中我们要执行一个事务,代码是这样的:
sqlMapClient.startTransaction ();
sqlMapClient.add (xxxxx);
sqlMapClient.update (xxxxx);
sqlMapClient.commitTransaction ();
看到这段代码你会不会有一个问题,sqlMapClient里面到底是怎么做的?
我能猜到有两种做法:
1. 调用sqlMapClient.startTransaction时会通知数据库事务开始了,然后依次执行add和update,最后告诉数据库提交事务。
2.调用sqlMapClient.startTransaction时并没有通知数据库,只不过在sqlMapClient这个对象中记录了一个标志,然后下面的add操作与update操作也没有实际上执行语句,只是产生了sql语句并存储在sqlMapClient中。最终调用sqlMapClient.commitTransaction时,会把产生的这些sql语句作为一个事务一次提交执行。
google了一下,没发现有人提出这样的问题。只好自己看源码。下面是源码的调用关系。
SqlMapClientImpl.startTransaction() --->
public void startTransaction(int transactionIsolation) throws SQLException {
getLocalSqlMapSession().startTransaction(transactionIsolation);
}
这里的 getLocalSqlMapSession()返回了一个SqlMapSession对象,这个对象非常重要,它管理了一次事务的状态,为什么重要后面会讲到。
继续跟踪调用
------>SqlMapSessionImpl.startTransaction(transactionIsolation)
------>SqlMapExecutorDelegate.startTransaction(session, transactionIsolation)
------>TransactionManager.begin(session, transactionIsolation)这个方法是重点,看代码:
public void begin(SessionScope session, int transactionIsolation) throws SQLException, TransactionException {
Transaction trans = session.getTransaction();
TransactionState state = session.getTransactionState();
if (state == TransactionState.STATE_STARTED) {
throw new TransactionException("TransactionManager could not start a new transaction. " +
"A transaction is already started.");
} else if (state == TransactionState.STATE_USER_PROVIDED) {
throw new TransactionException("TransactionManager could not start a new transaction. " +
"A user provided connection is currently being used by this session. " +
"The calling .setUserConnection (null) will clear the user provided transaction.");
}
txThrottle.increment();
try {
trans = transactionConfig.newTransaction(transactionIsolation);
-------------------------------------------------------------------
session.setCommitRequired(false);
} catch (SQLException e) {
txThrottle.decrement();
throw e;
} catch (TransactionException e) {
txThrottle.decrement();
throw e;
}
session.setTransaction(trans);
----------------------------------------------
session.setTransactionState(TransactionState.STATE_STARTED);
}
注意用横线标出的那两句,首先创建了一个Transcaction,然后把它放入了session,为什么放入session,很重要,继续往下看。
transactionConfig.newTransaction(transactionIsolation);中创建了一个JdbcTransaction
看看JdbcTransaction的代码:
public class JdbcTransaction implements Transaction {
private static final Log connectionLog = LogFactory.getLog(Connection.class);
private DataSource dataSource;
private Connection connection;
private IsolationLevel isolationLevel = new IsolationLevel();
public JdbcTransaction(DataSource ds, int isolationLevel) throws TransactionException {
// Check Parameters
dataSource = ds;
if (dataSource == null) {
throw new TransactionException("JdbcTransaction initialization failed. DataSource was null.");
}
this.isolationLevel.setIsolationLevel(isolationLevel);
}
private void init() throws SQLException, TransactionException {
// Open JDBC Transaction
connection = dataSource.getConnection();
if (connection == null) {
throw new TransactionException("JdbcTransaction could not start transaction. Cause: The DataSource returned a null connection.");
}
// Isolation Level
isolationLevel.applyIsolationLevel(connection);
// AutoCommit
if (connection.getAutoCommit()) {
connection.setAutoCommit(false);
}
// Debug
if (connectionLog.isDebugEnabled()) {
connection = ConnectionLogProxy.newInstance(connection);
}
}
public void commit() throws SQLException, TransactionException {
if (connection != null) {
connection.commit();
}
}
public void rollback() throws SQLException, TransactionException {
if (connection != null) {
connection.rollback();
}
}
public void close() throws SQLException, TransactionException {
if (connection != null) {
try {
isolationLevel.restoreIsolationLevel(connection);
} finally {
connection.close();
connection = null;
}
}
}
public Connection getConnection() throws SQLException, TransactionException {
if (connection == null) {
init();
}
return connection;
}
}
它在Init方法中调用了
connection.setAutoCommit(false);来开始一个事务。
但是Init方法并没有在构造方法中调用啊。那它是什么时候被调用的呢?
仔细看一下,是在getConnection()方法中调用。那getConnection()又是什么时候被调用呢。回头想一下,前面我们把这个创建出来的transcation对象放入了session,在事务中第一次操作数据库的时候,比如说add操作时,就会从session中把这个transcation对象拿出来,然后调用getConnection()方法。这时就会通知数据库开始一个事务。
到现在为止,我们的问题应该清楚了。我刚开始提出来的两个猜想都不完全正确。不过第一个猜想更接近一点。
正确的答案是:
调用sqlMapClient.startTransaction时并没有通知数据库开始事务。但也不是最后commit时一次提交。
而是在调用sqlMapClient.startTransaction后,第一次执行数据库操作时通知数据库开始事务,在我们的例子中,就是sqlMapClient.add (xxxxx)的这个时机。
分享到:
相关推荐
iBatis是一个优秀的Java持久层框架,它主要负责数据库的交互,通过XML或注解方式配置和映射SQL,使得开发者能够将精力集中在业务逻辑上,而不是繁琐的JDBC代码。iBatis的核心思想是将SQL语句和Java代码分离,提供了...
在IT行业中,分布式事务处理是复杂系统架构中的一个重要环节,特别是在多数据库或服务协同工作的场景下。本项目“spring+jotm+ibatis+mysql实现JTA分布式事务”旨在利用这些技术来确保在分布式环境中的数据一致性。...
iBatis,全称为MyBatis iBatis,是一个基于Java的持久层框架,它简化了数据库与应用程序之间的交互,避免了直接编写大量的SQL语句和手动处理结果集。在这个过程中,iBatis提供了一个SQL映射框架,允许开发者将SQL...
根据提供的文件信息,本文将详细解析如何在Spring与ibatis框架整合时,通过特定配置来保留ibatis事务处理机制,并实现对事务的自定义控制。文章将围绕标题、描述及部分代码片段展开讨论。 ### Spring与ibatis整合...
在IT行业中,数据库操作是应用开发的核心部分,而Ibatis作为一个优秀的持久层框架,提供了灵活的SQL映射机制,使得数据库操作更为简单高效。本文将深入探讨如何利用Ibatis实现一对多关系、批处理、事务管理和与...
在IT行业中,Spring框架与iBatis(现为MyBatis)是两个广泛使用的开源工具。Spring是一个全面的Java企业级应用开发框架,而iBatis(MyBatis)则是一个优秀的持久层框架,它简化了数据库操作。当我们谈论"spring+...
iBATIS DAO(Data Access Object)框架中的事务管理是该框架的重要组成部分之一。它不仅负责管理事务连接池,还能够处理多个ORM(Object Relational Mapping)环境下的事务操作。本文将深入探讨iBATIS DAO事务管理的...
在数据库管理系统中,事务有四个特性,通常称为ACID属性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。 **2. Ibatis中的事务控制** 在Ibatis中,事务管理可以通过...
每次执行SQL时,都会检查当前是否在一个活跃的事务中,如果没有,就会自动开始一个新的事务。 标签 "工具" 可能指的是使用一些辅助工具来帮助理解Ibatis的事务处理,比如IDE的调试功能,可以跟踪代码执行流程,查看...
虽然原生的IBATIS是为Java设计的,但C#也有类似的框架,如MyBatis.NET,它是.NET平台上的一个ORM框架,功能和使用方式与Java的IBATIS类似。MyBatis.NET同样提供SQL映射和对象关系映射功能,帮助开发人员更方便地操作...
根据提供的文件信息,本文将详细解析Spring与iBatis整合时如何保留并使用iBatis事务管理机制,以及如何在应用程序中实现手动控制事务的方法。 ### Spring与iBatis整合 Spring框架是一个全面的企业级应用开发框架,...
IBATIS是一个流行的Java和.NET平台上的数据访问层解决方案,它允许开发者编写SQL语句并与对象模型进行交互,而无需传统的JDBC或ADO.NET代码。对于多数据库支持,IBATIS提供了配置和动态切换的能力,使得在不同数据库...
在IT行业中,Spring框架与iBatis(现为MyBatis)是两个广泛使用的开源工具,主要用于构建企业级Java应用程序。本示例“spring+ibatis声明式事务Demo”将探讨如何在Spring与iBatis集成环境中使用声明式事务管理。声明...
### 操作数据库iBATIS查询详解 #### 一、iBATIS中的LIKE查询技巧 ...通过以上配置,iBATIS能够有效地管理与数据库的交互过程,并提供强大的查询功能。在实际开发过程中,根据项目需求合理配置这些参数是非常重要的。
本教程将围绕“简单的ibatis与mysql的交互”这一主题展开,帮助初学者理解如何在Eclipse环境下使用Ibatis与MySQL数据库进行交互。 首先,Ibatis的核心理念是将SQL语句写在XML配置文件中,这样既保持了代码的整洁,...
很好的spring+ibatis事务的配置文档.
标题 "ibatis.net winform搭建带数据库" 描述了一个使用iBATIS.NET框架在Windows Forms(WinForm)应用程序中构建数据库交互的过程。iBATIS.NET是.NET平台上的一个持久层框架,它允许开发者将SQL语句与应用程序代码...
iBatis 是一个轻量级的 Java 框架,它将 SQL 查询与 Java 代码分离,提高了可维护性和可测试性。 在描述中提到的 "NULL" 可能是因为原始描述内容缺失或已删除,因此我们无法直接获取更多的信息。但根据标题,我们...
【ibatis入门--对数据库的操作】这篇文章主要讲解了如何使用iBatis框架来操作数据库,iBatis是一个轻量级的持久层框架,它将SQL语句与Java代码分离,提高了开发效率和代码的可维护性。以下是文章涉及的关键知识点: ...
在这个小例子中,我们已经成功地用Ibatis连接上了ORACLE数据库,并执行了一个简单的查询操作。Ibatis允许我们灵活地编写SQL,同时提供了事务管理和结果映射等功能,使得数据库操作更加便捷和高效。 注意,为了运行...