Mybatis配置文件可配置事务管理模式
XML
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!-- 数据源配置 -->
</dataSource>
</environment>
</environments>
事务管理模式配置
1. JDBC 事务管理器(JDBC Transaction Manager)
特点:直接使用 JDBC 的事务管理机制
配置:通过 JdbcTransactionFactory 类实现
适用场景:简单的单数据源应用
2. 外部事务管理器(MANAGED Transaction Manager)
特点:将事务管理委托给外部容器(如 Spring、JBoss 等)
配置:通过 ManagedTransactionFactory 类实现
适用场景:集成到支持事务管理的框架中
3. 自定义事务管理器
特点:允许开发者实现自己的事务管理逻辑
配置:通过实现 TransactionFactory 接口来自定义事务行为
|---------|------|---------|------|
| 事务管理器 | 事务控制 | 提交回滚 | 适用场景 |
| JDBC | 直接控制 | 手动提交/回滚 | 简单应用 |
| MANAGED | 容器控制 | 容器自动管理 | 框架集成 |
自定义实现,基于JDBC的基础上
自定提交事务实现
java
package com.lym.system.core.transaction;
import org.apache.ibatis.transaction.Transaction;
import org.springframework.jdbc.datasource.ConnectionHolder;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.Assert;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
public class LymTransaction implements Transaction {
private final DataSource dataSource;
private Connection connection;
private boolean isConnectionTransactional;
private boolean autoCommit;
// public GyTransaction(DataSource dataSource) {
// this.dataSource = dataSource;
// }
public LymTransaction(DataSource dataSource) {
Assert.notNull(dataSource, "No DataSource specified");
this.dataSource = dataSource;
}
public Connection getConnection() throws SQLException {
if (this.connection == null) {
this.openConnection();
}
return this.connection;
}
private void openConnection() throws SQLException {
this.connection = DataSourceUtils.getConnection(this.dataSource);
this.connection.setAutoCommit(true);
this.autoCommit = this.connection.getAutoCommit();
this.isConnectionTransactional = DataSourceUtils.isConnectionTransactional(this.connection, this.dataSource);
}
public void commit() throws SQLException {
if (this.connection != null && !this.isConnectionTransactional && !this.autoCommit) {
this.connection.commit();
}
}
public void rollback() throws SQLException {
if (this.connection != null && !this.isConnectionTransactional && !this.autoCommit) {
this.connection.rollback();
}
}
public void close() throws SQLException {
if (this.connection != null) {
this.connection.setAutoCommit(this.autoCommit);
DataSourceUtils.releaseConnection(this.connection, this.dataSource);
}
}
public Integer getTimeout() throws SQLException {
ConnectionHolder holder = (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);
return holder != null && holder.hasTimeout() ? holder.getTimeToLiveInSeconds() : null;
}
}
手动控制事务提交实现
java
package com.lym.system.core.transaction;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.transaction.Transaction;
import org.springframework.jdbc.datasource.ConnectionHolder;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.Assert;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
public class LymThreadTransaction implements Transaction {
private static final Log LOGGER = LogFactory.getLog(LymThreadTransaction.class);
private final DataSource dataSource;
private Connection connection;
private boolean isConnectionTransactional;
private boolean autoCommit;
public LymThreadTransaction(DataSource dataSource) {
Assert.notNull(dataSource, "No DataSource specified");
this.dataSource = dataSource;
}
public Connection getConnection() throws SQLException {
if (this.connection == null) {
this.openConnection();
}
return this.connection;
}
private void openConnection() throws SQLException {
this.connection = DataSourceUtils.getConnection(this.dataSource);
this.autoCommit = this.connection.getAutoCommit();
this.isConnectionTransactional = DataSourceUtils.isConnectionTransactional(this.connection, this.dataSource);
}
public void commit() throws SQLException {
}
public void doCommit() throws SQLException {
if (this.connection != null && !this.isConnectionTransactional && !this.autoCommit) {
this.connection.commit();
}
}
public void doClose() throws SQLException {
if (this.connection != null) {
this.connection.setAutoCommit(this.autoCommit);
}
DataSourceUtils.releaseConnection(this.connection, this.dataSource);
}
public void rollback() throws SQLException {
if (this.connection != null && !this.isConnectionTransactional && !this.autoCommit) {
this.connection.rollback();
}
}
public void close() throws SQLException {
}
public Integer getTimeout() throws SQLException {
ConnectionHolder holder = (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);
return holder != null && holder.hasTimeout() ? holder.getTimeToLiveInSeconds() : null;
}
}
事务管理器自定义实现
java
package com.lym.system.core.transaction;
import org.apache.ibatis.session.TransactionIsolationLevel;
import org.apache.ibatis.transaction.Transaction;
import org.apache.ibatis.transaction.TransactionFactory;
import javax.sql.DataSource;
import java.sql.Connection;
import java.util.Properties;
public class LymTransactionFactory implements TransactionFactory {
private String dataSourceId;
private ThreadLocal<Transaction> transactionLocal = new ThreadLocal();
public LymTransactionFactory() {
}
public void setProperties(Properties props) {
}
public Transaction getTransaction() {
return (Transaction)this.transactionLocal.get();
}
public void clear() {
this.transactionLocal.set((Transaction) null);
}
public Transaction newTransaction(Connection conn) {
throw new UnsupportedOperationException("New Spring transactions require a DataSource");
}
public Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit) {
if (ManagerTransaction.isThreadTransaction()) {
Transaction transaction = (Transaction)this.transactionLocal.get();
if (transaction != null) {
return transaction;
} else {
transaction = new LymThreadTransaction(dataSource);
this.transactionLocal.set(transaction);
ManagerTransaction.addTransactionFactory(this);
return transaction;
}
} else {
return new LymTransaction(dataSource);
}
}
public String getDataSourceId() {
return this.dataSourceId;
}
public void setDataSourceId(String dataSourceId) {
this.dataSourceId = dataSourceId;
}
}
线程事务管理器
java
package com.lym.system.core.transaction;
import org.apache.ibatis.transaction.Transaction;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ManagerTransaction {
private static ThreadLocal<Boolean> threadTransaction = new ThreadLocal();
private static ThreadLocal<List<LymTransactionFactory>> threadTransactionFactories = new ThreadLocal();
public ManagerTransaction() {
}
public static boolean isThreadTransaction() {
return threadTransaction.get() == null ? false : (Boolean)threadTransaction.get();
}
public static void setThreadTransaction(boolean isThreadTransaction) {
threadTransaction.set(isThreadTransaction);
}
public static synchronized void addTransactionFactory(LymTransactionFactory transactionFactory) {
List<LymTransactionFactory> lst = (List<LymTransactionFactory>)threadTransactionFactories.get();
if (lst == null) {
lst = new ArrayList();
threadTransactionFactories.set(lst);
}
((List<LymTransactionFactory>)lst).add(transactionFactory);
}
public static synchronized void commitAndClose() throws SQLException {
List<LymTransactionFactory> lst = (List<LymTransactionFactory>)threadTransactionFactories.get();
if (lst != null) {
Iterator<LymTransactionFactory> it = lst.iterator();
while(true) {
while(true) {
if (!it.hasNext()) {
return;
}
LymTransactionFactory factory = (LymTransactionFactory)it.next();
try {
Transaction transaction = factory.getTransaction();
if (transaction != null) {
if (transaction instanceof LymThreadTransaction) {
try {
((LymThreadTransaction)transaction).doCommit();
} finally {
((LymThreadTransaction)transaction).doClose();
}
} else {
try {
transaction.commit();
} finally {
transaction.close();
}
}
break;
}
} finally {
factory.clear();
}
}
it.remove();
}
}
}
public static synchronized void rollbackAndClose() throws SQLException {
List<LymTransactionFactory> lst = (List<LymTransactionFactory>)threadTransactionFactories.get();
if (lst != null) {
Iterator<LymTransactionFactory> it = lst.iterator();
while(true) {
while(true) {
if (!it.hasNext()) {
threadTransactionFactories.set((List<LymTransactionFactory>) null);
return;
}
LymTransactionFactory factory = (LymTransactionFactory)it.next();
try {
Transaction transaction = factory.getTransaction();
if (transaction != null) {
if (transaction instanceof LymThreadTransaction) {
try {
transaction.rollback();
} finally {
((LymThreadTransaction)transaction).doClose();
}
} else {
try {
transaction.rollback();
} finally {
transaction.close();
}
}
break;
}
} finally {
factory.clear();
}
}
it.remove();
}
}
}
}
测试
java
ManagerTransaction.setThreadTransaction(true);
try {
Integer i = sysUserSerivce.addUserInfo(lymUserV);
//打印数据和执行结果
System.out.println(lymUserV);
System.out.println(i);
if (needRollback) {
// 测试回滚功能
ManagerTransaction.rollbackAndClose();
return ResultUtils.success("已执行回滚测试");
} else {
// 正常提交事务
ManagerTransaction.commitAndClose();
Map map = new HashMap<>();
map.put("message", "添加成功");
return ResultUtils.success(map);
}
} catch (Exception e) {
try {
// 发生异常时回滚
ManagerTransaction.rollbackAndClose();
} catch (SQLException rollbackEx) {
System.err.println("回滚时发生异常: " + rollbackEx.getMessage());
}
return ResultUtils.fail("操作失败:" + e.getMessage());
} finally {
// 关闭线程事务
ManagerTransaction.setThreadTransaction(false);
}
其他
当前模式实现基于spring+mybatis的配置基础上实现,未使用代理对象,容器管理,如使用springboot请使用直接使用编程式事务管理、声明式事务管理