我的问题非常接近Sharing a transaction while using AbstractRoutingDataSource to switch datasources,但我无法使用接受的答案解决。我有一个事务方法,他必须在事务模式下将同一个实体写入两个不同的数据源。当事务提交我有一个
Internal Exception: java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint (VETO_PROD.SYS_C0013988) violated
这是我的Transalctional方法:
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public ContactTypeJson definisciNuovaContactType(String descrizione) throws Exception {
String functionCode = RandomStringUtils.randomAlphanumeric(5).toUpperCase();
LOGGER.debug("Ho generato la functionCode[" + functionCode + "]");
while (!isContactTypeAvailable(functionCode) || !notificatorService.isFunctionCodeAvailable(functionCode)) {
LOGGER.debug("La functionCode[" + functionCode + "] e' gia' in utilizzo, genero una nuova...");
functionCode = RandomStringUtils.randomAlphanumeric(5).toUpperCase();
LOGGER.debug("...la nuova functionCode generata e' [" + functionCode + "]");
}
ContactType contactType = new ContactType();
contactType.setName(functionCode);
contactType.setDescription(descrizione);
notificatorService.insertNewFunction(functionCode, descrizione);
entityManagerFRVP0.flush();
entityManagerFRVP0.clear();
VetrinaContextHolder.setTargetDataSource(VetrinaToolConstants.FRVP_DATASOURCE);
entityManagerFRVP0.persist(contactType);
entityManagerFRVP0.flush();
entityManagerFRVP0.clear();
VetrinaContextHolder.setTargetDataSource(VetrinaToolConstants.PWVP_DATASOURCE);
ContactType contactType1 = new ContactType();
contactType1.setName(functionCode);
contactType1.setDescription(descrizione);
entityManagerFRVP0.persist(contactType1);
VetrinaContextHolder.clearTargetDataSource();
ContactTypeToJsonConverter converter = new ContactTypeToJsonConverter();
return converter.convert(contactType);
}
这是JPA日志:
2013-07-15 10:47:59,570 DEBUG [sql] 2013-07-15 10:47:59.569--ServerSession(26361419)--Connection(16434777)--Thread(Thread[[ACTIVE] ExecuteThread: '18' for queue: 'weblogic.kernel.Default (self-tuning)',5,Pooled Threads])--SELECT VET_SEQ_CONTACT_TYPE.NEXTVAL FROM DUAL
2013-07-15 10:47:59,581 DEBUG [sql] 2013-07-15 10:47:59.58--ClientSession(21299255)--Connection(17900213)--Thread(Thread[[ACTIVE] ExecuteThread: '18' for queue: 'weblogic.kernel.Default (self-tuning)',5,Pooled Threads])--INSERT INTO S_VET_CONTACT_TYPE (ID, DESCRIPTION, NAME, FASEDIDEFAULT_ID) VALUES (81, Prova doppione, 16XOV, NULL)
2013-07-15 10:47:59,596 DEBUG [sql] 2013-07-15 10:47:59.595--ClientSession(21299255)--Connection(17900213)--Thread(Thread[[ACTIVE] ExecuteThread: '18' for queue: 'weblogic.kernel.Default (self-tuning)',5,Pooled Threads])--SELECT VET_SEQ_CONTACT_TYPE.NEXTVAL FROM DUAL
2013-07-15 10:47:59,601 DEBUG [sql] 2013-07-15 10:47:59.6--ClientSession(21299255)--Connection(17900213)--Thread(Thread[[ACTIVE] ExecuteThread: '18' for queue: 'weblogic.kernel.Default (self-tuning)',5,Pooled Threads])--INSERT INTO S_VET_CONTACT_TYPE (ID, DESCRIPTION, NAME, FASEDIDEFAULT_ID) VALUES (82, Prova doppione, 16XOV, NULL)
这个堆栈:
2013-07-15 10:47:59,421 DEBUG [WebLogicJtaTransactionManager] Creating new transaction with name [com.intesasanpaolo.frvp0.alten.vetrinatool.service.console.ConsoleServiceImpl.definisciNuovaContactType]: PROPAGATION_REQUIRES_NEW,ISOLATION_DEFAULT; ''
2013-07-15 10:47:59,430 DEBUG [EntityManagerFactoryUtils] Opening JPA EntityManager
2013-07-15 10:47:59,430 DEBUG [EntityManagerFactoryUtils] Registering transaction synchronization for JPA EntityManager
2013-07-15 10:47:59,483 DEBUG [TransactionalRepositoryProxyPostProcessor$CustomAnnotationTransactionAttributeSource] Adding transactional method 'findOne' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly; ''
2013-07-15 10:47:59,483 DEBUG [DefaultListableBeanFactory] Returning cached instance of singleton bean 'transactionManager'
2013-07-15 10:47:59,483 DEBUG [WebLogicJtaTransactionManager] Participating in existing transaction
2013-07-15 10:47:59,483 DEBUG [EntityManagerFactoryUtils] Opening JPA EntityManager
2013-07-15 10:47:59,483 DEBUG [EntityManagerFactoryUtils] Registering transaction synchronization for JPA EntityManager
2013-07-15 10:47:59,542 DEBUG [AnnotationTransactionAttributeSource] Adding transactional method 'insertNewFunction' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
2013-07-15 10:47:59,543 DEBUG [DefaultListableBeanFactory] Returning cached instance of singleton bean 'transactionManager'
2013-07-15 10:47:59,543 DEBUG [WebLogicJtaTransactionManager] Participating in existing transaction
2013-07-15 10:47:59,543 DEBUG [DefaultListableBeanFactory] Returning cached instance of singleton bean 'transactionManager'
2013-07-15 10:47:59,543 DEBUG [WebLogicJtaTransactionManager] Participating in existing transaction
2013-07-15 10:47:59,549 DEBUG [TransactionalRepositoryProxyPostProcessor$CustomAnnotationTransactionAttributeSource] Adding transactional method 'save' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
2013-07-15 10:47:59,549 DEBUG [DefaultListableBeanFactory] Returning cached instance of singleton bean 'transactionManager'
2013-07-15 10:47:59,550 DEBUG [WebLogicJtaTransactionManager] Participating in existing transaction
2013-07-15 10:47:59,600 DEBUG [EntityManagerFactoryUtils] Closing JPA EntityManager
2013-07-15 10:47:59,600 DEBUG [EntityManagerFactoryUtils] Closing JPA EntityManager
2013-07-15 10:47:59,600 DEBUG [WebLogicJtaTransactionManager] Initiating transaction commit
2013-07-15 10:47:59,827 DEBUG [DispatcherServlet] Handler execution resulted in exception - forwarding to resolved error view: ModelAndView: reference to view with name 'jsonView'; model is {hasErrors=true, errorCode=GEN_EX, errorMessages=Errore generico}
org.springframework.transaction.UnexpectedRollbackException: JTA transaction unexpectedly rolled back (maybe due to a timeout); nested exception is weblogic.transaction.RollbackException: Unexpected exception in beforeCompletion: sync=org.eclipse.persistence.transaction.JTASynchronizationListener@2f0af4
Internal Exception: java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint (VETO_PROD.SYS_C0013988) violated
Error Code: 1
Call: INSERT INTO S_VET_CONTACT_TYPE (ID, DESCRIPTION, NAME, FASEDIDEFAULT_ID) VALUES (82, 'Prova doppione', '16XOV', NULL)
Query: InsertObjectQuery(ContactType [id=82, name=16XOV, description=Prova doppione, fasiAssociate={[]}, faseDiDefault=null])
at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1014)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:755)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:724)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:387)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at com.sun.proxy.$Proxy310.definisciNuovaContactType(Unknown Source)
at com.intesasanpaolo.frvp0.alten.vetrinatool.mvc.console.controller.CreaContactTypeController.creaNuovaContactType(CreaContactTypeController.java:30)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
我正在使用带有XA数据源的WebLogic 10.3.5和org.springframework.transaction.jta.WebLogicJtaTransactionManager
有什么想法吗?
答案 0 :(得分:1)
您违反了唯一约束。我假设您在联系人姓名上定义了一个,因此您无法插入两个具有相同名称的联系人。
尝试在动态下切换DataSource下的连接似乎是一个非常非常糟糕的主意。相反,你应该有两个持久性单元,一个到一个数据库,一个到另一个。
您可能还想调查EclipseLink的数据分区或复合持久性单元。
http://wiki.eclipse.org/EclipseLink/Examples/JPA/Partitioning