提问者:小点点

JavaSpring事务管理


如果以前有人问过这个或类似的问题,请原谅。我是Spring的新手。我的问题是,为什么事务管理器和JdbcTemplate使用相同的DB连接。在我能接触到的所有文档和书籍中,都说两个bean(事务管理器和JDBC模板)都有一个数据源。让它成为Apache Commons BasicDataSource。据我所知,两个对象在实例化时都将调用数据源的方法getConnection(),并将被赋予不同的连接。之后,JDBC模板的更新将在一个连接上执行,而事务管理器的提交将在另一个连接中执行。绝对不会发生交易行为。

我哪里错了?

事实上,我的程序有点复杂。它是多线程的,并且管理一个连接池。最初,每个线程都获得“连接”(实际上是JdbcTemplate对象),然后使用它直到终止。在它的生命周期中,它执行一系列数据库更新“批处理”,这些更新必须是事务性的。但是尝试使用@Transactional annotation失败了——如果一个批处理中有两个插入操作,而第二个操作失败,那么第一个操作不会回滚。

DataSourceTransactionManager和JdbcTemplate在beans.xml中都引用了相同的BasicDataSource。

很明显,在某些地方,我对Spring中的事务管理机制的理解大错特错,因为其他人很乐意使用它。但是到底在哪里呢?


共1个答案

匿名用户

实际上,您可以查看JdbcTemplate的来源。

您可以在那里看到它不直接从数据源获取连接,而是Connection con=DataSourceUtils. getConnection(getDataSource());代替。

这些DataSourceUtils负责从Spring线程本地连接容器中获取当前的事务连接,或者从数据源中实例化新的连接,并在容器中注册它(例如,如果它是事务中的第一个请求)。

另外,你不能用Spring事务机制以任何简单的方式让单个事务跨多个线程运行。