我是Spring的新手,我想知道是否可以在同一个应用程序中使用多个事务管理器?
我有两个数据访问层 - 一个用于两个数据库.我想知道,你如何为一层使用一个事务管理器而另一层使用不同的事务管理器.我不需要跨两个数据库执行事务.但我确实需要单独对每个数据库执行事务.我创建了一个图像来帮助概述我的问题:

这是我的应用程序上下文配置:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<context:component-scan base-package="cheetah.repositories" />
<tx:annotation-driven />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="accounts" />
</bean>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
</beans>
Run Code Online (Sandbox Code Playgroud)
以下是使用此配置的示例:
@Repository
public class JpaAccountRepository implements AccountRepository {
@PersistenceContext(unitName = "cheetahAccounts")
private EntityManager accountManager;
@Override
@Transactional
public Account findById(long id) {
Account account = accountManager.find(Account.class, id);
return account;
}
}
Run Code Online (Sandbox Code Playgroud)
因此,对于帐户存储库,我想使用实体管理器工厂,并将持久性单元设置为帐户.但是,使用我的BusinessData Repository,我想使用具有不同持久性单元的实体管理器工厂.由于我只能定义一个事务管理器bean,我如何为不同的存储库使用不同的事务管理器?
谢谢你的帮助.
基本上,它在锡上说的是什么; 我需要一个可在Java SE应用程序中使用的JTA实现,理想情况是它不会带来太多的框架负担.
我有一个现有的应用程序,它将Hibernate SessionFactory用于一个数据库.我们正在添加另一个数据库来进行分析.事务永远不会交叉,所以我不需要JTA,但我确实想要将JPA EntityManager用于新数据库.
我已经设置了EntityManager和新的事务管理器,我已经认可了,但是Spring抱怨我需要对现有的@Transactional注释进行限定.我试图找到一种方法告诉Spring使用txManager作为默认值.有没有办法做到这一点?否则,我将不得不将限定符添加到所有现有的@Transactional注释中,如果可能的话我想避免这些注释.
@Bean(name = "jpaTx")
public PlatformTransactionManager transactionManagerJPA() throws NamingException {
JpaTransactionManager txManager = new JpaTransactionManager(entityManagerFactory());
return txManager;
}
@Bean
public PlatformTransactionManager txManager() throws Exception {
HibernateTransactionManager txManager = new HibernateTransactionManager(sessionFactory());
txManager.setNestedTransactionAllowed(true);
return txManager;
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误
No qualifying bean of type [org.springframework.transaction.PlatformTransactionManager] is defined: expected single matching bean but found 2:
Run Code Online (Sandbox Code Playgroud)
谢谢
编辑:对于可能对此问题感兴趣的任何人,我在问题的最后提供了相关解决方案的问题分析.
我正在为Web应用程序配置模块,其中我使用的是Spring 3.2,Hibernate 4.1,Spring Data JPA 1.3和Apache CXF 2.5(特别是JAX-RS模块).我有以下配置(工作完全正常,为简明起见,省略了详细信息):
@Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean getEntityManagerFactory() throws SQLException{
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
//...
return factory;
}
@Bean(name = "transactionManager")
public JpaTransactionManager getTransactionManager() throws SQLException{
JpaTransactionManager manager = new JpaTransactionManager();
//...
return manager;
}
@Bean(name = "persistenceExceptionTranslator")
public PersistenceExceptionTranslator getPersistenceExceptionTranslator(){
return new HibernateExceptionTranslator();
}
Run Code Online (Sandbox Code Playgroud)
我的问题是我必须依赖一些定义自己的外部模块PlatformTransactionManager,所以我发现自己同时使用更多的事务管理器.Transactional.html #value()可以很容易地解决这个问题,所以无论我需要在哪里使用@Transactional,我都要使用我必须用于该事务的事务管理器的名称来限定注释.
我想将我在模块中定义的事务管理器的名称更改为更有意义的名称,以满足外部模块的标准.因此,例如,externalModule1将其经理定义为externalModule1TransactionManager我想要的
@Bean(name = "myModuleransactionManager")
public JpaTransactionManager getTransactionManager() throws SQLException{
JpaTransactionManager manager = new JpaTransactionManager(); …Run Code Online (Sandbox Code Playgroud) 我找到了以下主题:JdbcTemplate与TransactionManager如何一起工作?
第一句话:
据我所知,DataSourceTransactionManager将JDBC连接从指定的DataSource绑定到当前线程,允许每个DataSource一个线程绑定连接.如果它是一个连接池,它将采用一个可用的连接.
......正是我想知道的.
使用事务管理器时,您最终是否拥有自己的单个连接的每个线程?此外,该连接存在多长时间?同一个线程是否在单个请求中使用相同的连接,或者还有其他事情在进行?我只是想了解一下当你有一个事务管理器时Spring正在做什么,而当你没有事务管理器时(无论你是否真的有一个事务).
我正在尝试创建基于Spring的解决方案,以便在MySQL 5.5服务器上运行批量SQL查询."查询"是指任何编译的SQL语句,因此SQL批处理作业可以包含例如几个CREATE TABLE,DELETE和INSERT语句.
我正在使用Spring Batch来达到这个目的.
我transactionManager配置如下.
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
Run Code Online (Sandbox Code Playgroud)
和dataSource:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${batch.jdbc.driver}" />
<property name="url" value="${batch.jdbc.url}" />
<property name="username" value="${batch.jdbc.user}" />
<property name="password" value="${batch.jdbc.password}" />
<property name="maxIdle" value="10" />
<property name="maxActive" value="100" />
<property name="maxWait" value="10000" />
<property name="validationQuery" value="select 1" />
<property name="testOnBorrow" value="false" />
<property name="testWhileIdle" value="true" />
<property name="timeBetweenEvictionRunsMillis" value="1200000" />
<property name="minEvictableIdleTimeMillis" value="1800000" />
<property name="numTestsPerEvictionRun" value="5" …Run Code Online (Sandbox Code Playgroud) 当我们可以通过会话在hibernate中进行事务时,需要HibernateTransactionManager再次Spring-hibernate集成什么?
它的作用是什么?
为什么我们不能直接进行交易呢?
使用Spring + Hibernate和事务注释.
我正在尝试测试以下内容:
@Transactional服务方法来持久化它我遇到的第一个问题是在步骤2中读取User对象,只返回Hibernate 1级缓存中的那个,并且实际上没有从数据库中读取.
因此,我使用Session手动从缓存中驱逐对象以强制从数据库读取.但是,当我这样做时,对象值永远不会在单元测试中持久存在(我知道在测试完成后它会因为我指定的设置而回滚).
我尝试在调用@Transactionalservice方法后手动刷新会话,并且DID提交更改.但是,这不是我的预期.我认为@Transactional服务方法可以确保事务已提交并且会话在返回之前刷新.我知道Spring一般会决定何时进行这种管理,但我认为方法中的"工作单元" @Transactional就是这种方法.
无论如何,现在我想弄清楚我将如何测试@Transactional一般的方法.
这是一个失败的junit测试方法:
@RunWith(SpringJUnit4ClassRunner.class)
@Transactional
@TransactionConfiguration(transactionManager = "userTransactionManager", defaultRollback = true)
@WebAppConfiguration()
@ContextConfiguration(locations = { "classpath:test-applicationContext.xml",
"classpath:test-spring-servlet.xml",
"classpath:test-applicationContext-security.xml" })
public class HibernateTest {
@Autowired
@Qualifier("userSessionFactory")
private SessionFactory sessionFactory;
@Autowired
private UserService userService;
@Autowired
private PaymentService paymentService;
@Autowired
private QueryService queryService;
@Autowired
private NodeService nodeService;
@Autowired
private UserUtils userUtils;
@Autowired
private UserContext userContext;
@Test
public void testTransactions() {
// read the user …Run Code Online (Sandbox Code Playgroud) spring hibernate sessionfactory transactional transactionmanager
TransactionManagementType.CONTAINER 和 TransactionManagementType.BEAN 有什么区别
因为我在我所有的 EJB 中使用 TransactionManagementType.CONTAINER 并且当使用多个数据库实例时,它会抛出一个错误,如果我将其更改为 TransactionManagementType.BEAN
我想知道如果我将其更改为 TransactionManagementType.BEAN 有什么优点和缺点以及如何影响它
ERROR:
Error updating database. Cause: java.sql.SQLException: javax.resource.ResourceException:
IJ000457: Unchecked throwable in managedConnectionReconnected() cl=org.jboss.jca.core.
connectionmanager.listener.TxConnectionListener@680f2be0[state=NORMAL managed
connection=org.jboss.jca.adapters.jdbc.local.LocalManagedConnection@7ba33a94 connection
handles=0 lastReturned=1495691675021 lastValidated=1495690817487
lastCheckedOut=1495691675018 trackByTx=false pool=org.jboss.jca.core.connectionmanager.
pool.strategy.OnePool@efd42c4 mcp=SemaphoreConcurrentLinkedQueueManagedConnectionPool
@71656eec[pool=FAQuery] xaResource=LocalXAResourceImpl@4c786e85
[connectionListener=680f2be0 connectionManager=5c3b98bc warned=false
currentXid=null productName=Oracle productVersion=Oracle Database 12c
Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
jndiName=java:/FAQuery] txSync=null]
Run Code Online (Sandbox Code Playgroud) transactionmanager spring-transactions ejb-3.0 spring-mybatis
我不太确定如何制定这个问题,所以请随时告诉我,我在想完全错误.
我想用JdbcTemplate和TransactionTemplate.我开始通过初始化我的连接池作为数据源并创建一个事务管理器作为数据源以及?
BoneCPConfig connectionPoolConfig = new BoneCPConfig();
connectionPoolConfig.setJdbcUrl(...);
connectionPoolConfig.setUsername(...);
connectionPoolConfig.setPassword(...);
connectionPoolConfig.setMinConnectionsPerPartition(...);
connectionPoolConfig.setMaxConnectionsPerPartition(...);
dataSource = new BoneCPDataSource(connectionPoolConfig);
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
definition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
Run Code Online (Sandbox Code Playgroud)
但现在我想创建我的TransactionTemplate和JdbcTemplate:
transactionTemplate = new TransactionTemplate(transactionManager);
JdbcTemplate jdbc = new JdbcTemplate(transactionManager.getDataSource());
Run Code Online (Sandbox Code Playgroud)
现在mulitple线程访问transactionTemplate和jdbc.此代码是否保证所有内容都doInTransaction使用相同的连接进行所有jdbc调用?
连接是否以某种方式在内部链接,因为它看起来好像JdbcTemplate和TransactionTemplate可以使用他们想要的连接.我的代码是正确的/保存吗?
spring ×7
hibernate ×4
java ×3
jdbc ×2
jpa ×2
cxf ×1
database ×1
ejb-3.0 ×1
jdbctemplate ×1
jta ×1
spring-batch ×1
spring-mvc ×1
transactions ×1