评论

收藏

[MySQL] LDAP 与 MySql 连用 的JPA事物问题

数据库 数据库 发布于:2021-07-04 11:04 | 阅读数:573 | 评论:0

  本事甚是喜欢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的一个组织时,下面如果有分组,请不要家事物,否者你会发现 你并没删除掉并且还报错。

  
关注下面的标签,发现更多相似文章