本事甚是喜欢JPA简单方便明了,所以在LDAP项目要加上MYSQL数据库,但LDAP没有与jpa连用的事物处理 是一个很头疼的事,找到源码 发现里面只有2种对组合事物的支持:
ContextSourceAndDataSourceTransactionManager LDAP与JDBC的组合支持
ContextSourceAndHibernateTransactionManager LDAP与Hibernate的组合支持
如果使用这个 就是要说自己还要去封装jdbc 非常不爽,所以找到了个老外给的解决方法,自己写一个方法,来完成LDAP与JPA的组事物,下面就是 那段代码
import org.springframework.ldap.core.ContextSource; import org.springframework.ldap.transaction.compensating.TempEntryRenamingStrategy; import org.springframework.ldap.transaction.compensating.manager.ContextSourceTransactionManagerDelegate; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionException; import org.springframework.transaction.TransactionSuspensionNotSupportedException; import org.springframework.transaction.support.DefaultTransactionStatus; public class ContextSourceAndJpaTransactionManager extends JpaTransactionManager { private static final long serialVersionUID = 1L; private ContextSourceTransactionManagerDelegate ldapManagerDelegate = new ContextSourceTransactionManagerDelegate(); /** * @see org.springframework.orm.jpa.JpaTransactionManager#isExistingTransaction(Object) */ protected boolean isExistingTransaction(Object transaction) { ContextSourceAndJpaTransactionObject actualTransactionObject = (ContextSourceAndJpaTransactionObject) transaction; return super.isExistingTransaction(actualTransactionObject .getJpaTransactionObject()); } /** * @see org.springframework.orm.jpa.JpaTransactionManager#doGetTransaction() */ protected Object doGetTransaction() throws TransactionException { Object dataSourceTransactionObject = super.doGetTransaction(); Object contextSourceTransactionObject = ldapManagerDelegate.doGetTransaction(); return new ContextSourceAndJpaTransactionObject( contextSourceTransactionObject, dataSourceTransactionObject ); } /** * @see org.springframework.orm.jpa.JpaTransactionManager#doBegin(java.lang.Object, * org.springframework.transaction.TransactionDefinition) */ protected void doBegin(Object transaction, TransactionDefinition definition) throws TransactionException { ContextSourceAndJpaTransactionObject actualTransactionObject = (ContextSourceAndJpaTransactionObject) transaction; super.doBegin(actualTransactionObject.getJpaTransactionObject(), definition); ldapManagerDelegate.doBegin( actualTransactionObject.getLdapTransactionObject(), definition ); } /** * @see org.springframework.orm.jpa.JpaTransactionManager#doCleanupAfterCompletion(java.lang.Object) */ protected void doCleanupAfterCompletion(Object transaction) { ContextSourceAndJpaTransactionObject actualTransactionObject = (ContextSourceAndJpaTransactionObject) transaction; super.doCleanupAfterCompletion(actualTransactionObject .getJpaTransactionObject()); ldapManagerDelegate.doCleanupAfterCompletion(actualTransactionObject .getLdapTransactionObject()); } /** * @see org.springframework.orm.jpa.JpaTransactionManager#doCommit(org.springframework.transaction.support.DefaultTransactionStatus) */ protected void doCommit(DefaultTransactionStatus status) throws TransactionException { ContextSourceAndJpaTransactionObject actualTransactionObject = (ContextSourceAndJpaTransactionObject) status.getTransaction(); try { super.doCommit(new DefaultTransactionStatus( actualTransactionObject.getJpaTransactionObject(), status.isNewTransaction(), status.isNewSynchronization(), status.isReadOnly(), status.isDebug(), status.getSuspendedResources()) ); } catch (TransactionException ex) { if (isRollbackOnCommitFailure()) { logger.debug("Failed to commit db resource, rethrowing", ex); // If we are to rollback on commit failure, just rethrow the // exception - this will cause a rollback to be performed on // both resources. throw ex; } else { logger.warn( "Failed to commit and resource is rollbackOnCommit not set -" + " proceeding to commit ldap resource."); } } ldapManagerDelegate.doCommit(new DefaultTransactionStatus( actualTransactionObject.getLdapTransactionObject(), status.isNewTransaction(), status.isNewSynchronization(), status.isReadOnly(), status.isDebug(), status.getSuspendedResources()) ); } /** * @see org.springframework.orm.jpa.JpaTransactionManager#doRollback(org.springframework.transaction.support.DefaultTransactionStatus) */ protected void doRollback(DefaultTransactionStatus status) throws TransactionException { ContextSourceAndJpaTransactionObject actualTransactionObject = (ContextSourceAndJpaTransactionObject) status.getTransaction(); super.doRollback(new DefaultTransactionStatus( actualTransactionObject.getJpaTransactionObject(), status.isNewTransaction(), status.isNewSynchronization(), status.isReadOnly(), status.isDebug(), status.getSuspendedResources()) ); ldapManagerDelegate.doRollback(new DefaultTransactionStatus( actualTransactionObject.getLdapTransactionObject(), status.isNewTransaction(), status.isNewSynchronization(), status.isReadOnly(), status.isDebug(), status.getSuspendedResources()) ); } public ContextSource getContextSource() { return ldapManagerDelegate.getContextSource(); } public void setContextSource(ContextSource contextSource) { ldapManagerDelegate.setContextSource(contextSource); } protected void setRenamingStrategy(TempEntryRenamingStrategy renamingStrategy) { ldapManagerDelegate.setRenamingStrategy(renamingStrategy); } private final static class ContextSourceAndJpaTransactionObject { private Object ldapTransactionObject; private Object jpaTransactionObject; public ContextSourceAndJpaTransactionObject( Object ldapTransactionObject, Object jpaTransactionObject) { this.ldapTransactionObject = ldapTransactionObject; this.jpaTransactionObject = jpaTransactionObject; } public Object getJpaTransactionObject() { return jpaTransactionObject; } public Object getLdapTransactionObject() { return ldapTransactionObject; } } /** * @see org.springframework.orm.jpa.JpaTransactionManager#doSuspend(java.lang.Object) */ protected Object doSuspend(Object transaction) throws TransactionException { throw new TransactionSuspensionNotSupportedException( "Transaction manager [" + getClass().getName() + "] does not support transaction suspension"); } /** * @see org.springframework.orm.jpa.JpaTransactionManager#doResume(java.lang.Object, java.lang.Object) */ protected void doResume(Object transaction, Object suspendedResources) throws TransactionException { throw new TransactionSuspensionNotSupportedException( "Transaction manager [" + getClass().getName() + "] does not support transaction suspension"); } /** * @see org.springframework.orm.jpa.JpaTransactionManager#doSetRollbackOnly(org.springframework.transaction.support.DefaultTransactionStatus) */ @Override protected void doSetRollbackOnly(DefaultTransactionStatus status) { super.doSetRollbackOnly( new DefaultTransactionStatus( ((ContextSourceAndJpaTransactionObject)status.getTransaction()) .getJpaTransactionObject(), status.isNewTransaction(), status.isNewSynchronization(), status.isReadOnly(), status.isDebug(), status.getSuspendedResources()) ); } }
这事那人写的 一直没时间翻译 等有时间 得好好研究下 并写好注解。。。之后你的tx.xml要支持它 所以再看下我的tx.xml
<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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.1.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd" default-lazy-init="true" default-autowire="byName"> <bean id="transactionManager" class="com.smarcloud.control.util.ContextSourceAndJpaTransactionManager"> <!-- 第一个是LDAP的 --> <property name="contextSource" ref="contextSource"/> <!-- 第二个是Spring-Date-Jpa的 --> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean> <tx:annotation-driven transaction-manager="transactionManager" /> </beans>
这样就可以了 ,非常好用的 ,对了 对于删除ldap的一个组织时,下面如果有分组,请不要家事物,否者你会发现 你并没删除掉并且还报错。
转载于:https://blog.51cto.com/jueshizhanhun/1259803