在 Spring 管理的事务环境中,获取当前事务下的
JDBC Connection
✅ 方法一:通过 DataSourceUtils
获取(推荐)
Spring 提供了工具类 DataSourceUtils
,可以从当前事务中获取绑定的 Connection
。
示例代码:
import org.springframework.jdbc.datasource.DataSourceUtils;
import javax.sql.DataSource;
import java.sql.Connection;
@Autowired
private DataSource dataSource; // 注入数据源
public void someMethodInTransaction() {
Connection conn = DataSourceUtils.getConnection(dataSource);
try {
// 使用 conn 执行操作
System.out.println("Current connection: " + conn);
} finally {
DataSourceUtils.releaseConnection(conn, dataSource); // 可选:释放连接(如果是事务内,不会真正关闭)
}
}
⚠️ 注意:该方法适用于使用 Spring 声明式事务(如
@Transactional
)管理的上下文。它会自动绑定到当前线程的事务中。
✅ 方法二:通过 JdbcTemplate
获取(如果已使用 JdbcTemplate)
如果你已经在使用 JdbcTemplate
,可以通过其获取当前事务的连接:
示例代码:
@Autowired
private JdbcTemplate jdbcTemplate;
public void someMethodInTransaction() {
Connection conn = jdbcTemplate.getDataSource().getConnection();
// 或者更安全地获取当前事务连接:
Connection conn = DataSourceUtils.getConnection(jdbcTemplate.getDataSource());
}
✅ 方法三:通过 TransactionSynchronizationManager
获取绑定资源
如果你需要判断是否处于事务中,并获取底层资源(如 ConnectionHolder
),可以使用:
示例代码:
import org.springframework.transaction.support.TransactionSynchronizationManager;
public void checkIfInTransaction() {
if (TransactionSynchronizationManager.isActualTransactionActive()) {
Object resource = TransactionSynchronizationManager.getResource(dataSource);
if (resource instanceof ConnectionHolder) {
Connection conn = ((ConnectionHolder) resource).getConnection();
System.out.println("Current transaction connection: " + conn);
}
} else {
System.out.println("Not in transaction.");
}
}
✅ 方法四:自定义封装获取逻辑(适用于 AOP 或拦截器)
你也可以封装一个工具类来统一获取当前事务连接:
@Component
public class ConnectionHolder {
@Autowired
private DataSource dataSource;
public Connection getCurrentConnection() {
return DataSourceUtils.getConnection(dataSource);
}
public void releaseConnection(Connection conn) {
DataSourceUtils.releaseConnection(conn, dataSource);
}
}
然后在其他组件中注入并使用:
@Autowired
private ConnectionHolder connectionHolder;
public void doSomethingWithConnection() {
Connection conn = connectionHolder.getCurrentConnection();
try {
// 使用 conn
} finally {
connectionHolder.releaseConnection(conn);
}
}
✅ 总结对比
方法 | 是否支持事务绑定 | 是否推荐 | 说明 |
---|---|---|---|
DataSourceUtils.getConnection() | ✅ 是 | ✅ 推荐 | 最常用、最标准的方式 |
JdbcTemplate 获取 | ✅ 是 | ✅ 推荐 | 如果项目已用 JdbcTemplate |
TransactionSynchronizationManager | ✅ 是 | ⭐ 用于高级场景 | 检查事务状态和资源绑定 |
自定义封装 | ✅ 是 | ✅ 推荐 | 提高复用性和可维护性 |
📌 注意事项
- 不要手动调用
connection.close()
,除非你确定不在事务中; - 在事务中获取的连接是“逻辑连接”,实际连接由 Spring 管理;
- 如果未启用事务(即没有
@Transactional
),则每次获取的是新的连接。