如何在Spring交易中获取连接?

想象一下这段代码:

foo() {
     Connection conn = ...;
}

foo()已从具有注释 的方法调用。如何获取当前的 JDBC 连接?请注意,它位于bean中(因此它可以具有字段),但不能具有参数(因此我无法从某个位置传入连接)。@Transactionalfoo()@Autowiredfoo()

[编辑]我正在使用jOOQ,它需要数据源或连接。我的问题:我不知道配置了哪个事务管理器。它可以是任何东西;Java EE,基于DataSource,通过JNDI获取数据源。我的代码不是应用程序,而是库。我需要吞下别人放在我盘子里的东西。同样,我无法请求休眠会话工厂,因为使用我的应用程序可能不使用休眠。

但我知道其他代码,如Spring Hibernate集成,可以以某种方式从事务管理器获取当前连接。我的意思是,Hibernate不支持Spring的事务管理器,所以胶水代码必须使Spring API适应Hibernate的期望。我需要做同样的事情,但我无法弄清楚它是如何工作的。

[编辑2]我知道有一个活动的事务(即Spring在某个地方有一个连接实例,或者至少有一个可以创建一个事务管理器),但我的方法不是@Transactional。我需要调用一个作为参数的构造函数。我该怎么办?java.sql.Connection


答案 1

您可以尝试,根据 API,它应该返回数据源的当前连接。DataSourceUtils.getConnection(dataSource)

更新:根据您的意见和源代码:org.springframework.transaction.support.TransactionSynchronizationManager

就像我说的,获得连接的关键是数据源名称,如果无法获得,那么通过查看源代码的一种方法是尝试以下方法:

TransactionSynchronizationManager.getResourceMap()将返回当前线程中 ConnectionHolder 的数据源映射,假设事务中只涉及 1 个资源,则可以执行一个操作来获取第一个 ConnectionHolder,从中获取连接,方法是调用map.values().get(0).getConnection()

因此,基本上调用以下内容:

TransactionSynchronizationManager.getResourceMap().values().get(0).getConnection()

也许必须有更好的方法:-)


答案 2

(完全根据评论线程重写;不知道为什么我最初的答案集中在Hibernate上,除了我现在正在做的事情)

事务管理器与数据源完全正交。一些事务管理器直接与数据源交互,一些通过中间层(例如,Hibernate)进行交互,一些通过容器提供的服务(例如,JTA)进行交互。

当你将一个方法标记为 时,这意味着Spring在加载你的bean时会生成一个代理,并且该代理将被传递给任何其他想要使用你的bean的类。当调用代理的方法时,它(代理)要求事务管理器为其提供一个未完成的事务或创建一个新事务。然后它调用您的实际Bean方法。当 Bean 方法返回时,代理再次与事务管理器交互,说“我可以提交”或“我必须回滚”。这个过程有曲折;例如,一个事务方法可以调用另一个事务方法并共享同一事务。@Transactional

当事务管理器与 交互时,它不拥有 .不能要求事务管理器为您提供连接。相反,您必须注入一个将返回连接的特定于帧的对象(如休眠)。或者,您可以使用静态事务感知实用程序类,但这些类同样与特定框架相关联。DataSourceDataSourceSessionFactory


推荐