2016-09-13 7 views
0

Я новичок в Spring-Hibernate, и моя проблема такова: транзакция не сохраняет данные в таблице. Но не бросать никаких исключений. От линии@Transactional: Есть ли способ, с помощью которого спящий режим может продолжать дочернюю транзакцию, когда родительский сбой

Long id = logTransactionFileUpload(fileMetdataBean); 

в функции «logClientFile» (в «транзакционного» аннотированный класс класс/услуги, перечисленные ниже), я вижу возвращенного идентификатор, но данные не отображаются в таблице..

F inding является: это вложенные транзакции и откат, как родитель имел исключение из «msgProducer.send (сообщение, jmsConnectInfo)» в классе JobRunnerServiceImpl, в submitJob означает ме- после вставки дБ. Есть ли способ, с помощью которого спящий режим может продолжать дочернюю транзакцию при выходе из строя родителя?

Я не подозреваю, что моя конфигурация с пружиной/спящим режимом, так как сохранение других компонентов работает нормально. Только эта часть является проблемой.

FYI:

, если я включаю (в классе DAO осущ, перечисленных ниже)

//getCurrentSession().flush(); 
//getCurrentSession().getTransaction().commit(); 

Затем данные обнаруживаются в table.But этой фиксации и флеш не должно быть там, где используется @transactional.

Мой @Transactional аннотированный класс:

@Service("jobRunnerService") 
    @Transactional 
    public class JobRunnerServiceImpl implements JobRunnerService 
    { 
     private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); 



     @Autowired 
     @Qualifier("fileLoggerDao") 
     private IFileLoggerDAO fileLoggerDAO; 

     @Autowired 
     @Qualifier("fileMetaDataDao") 
     private IGenericDAO<FileMetaDataBean,Long> fileMetaDataDAO; 



     public void submitJob(String serviceName, String filePath, long clientId, long layoutId, String audienceId, 
       boolean isCA) 
     { 

      Map<String, String> parameters = new HashMap<String, String>(); 

      try 
      { 
       ..... doing something............ 

       LOG.info("Logging file information in FILE_META_DATA table... "); 
       String loggedFile = logClientFile(fileName, FACEBOOK_FILE_TYPE, fileExt, clientId, tpList); 

       ..... doing something............ 


       LOG.info(" Submitting job to JMS Q...."); 
       msgProducer.send(message, jmsConnectInfo);  

       //test code for the receiver to see if sent messages are received by receiver 
       //WildFlyJmsQueueReceive receiver = new WildFlyJmsQueueReceive(); 
       //receiver.receiveMessagesFromQueue(); 

      } 
      catch (Exception e) 
      { 
       String msg = "Error in JobRunnerServiceImpl.submitJob"; 
       LOG.error(msg,e); 
       throw new RuntimeException(msg,e); 
      } 

     } 



     private String logClientFile(String fileName, String fileType, String fileExt, long clientId, List<ToolkitPropertyBean> tpList)   
     { 
      ApplicationEnvironment enviro; 

      try 
      { 
       ..... doing something............ 


       //insert record in FILE_META_DATA table 
       FileMetaDataBean fileMetdataBean = new FileMetaDataBean(fileId, new Long(fileTypeID), fileName, fbFilePickUpDir +java.nio.file.FileSystems.getDefault().getSeparator()+ currentFile.getName(), receivedDate,new Long(FileUtilities.getRecordCount(currentFile)).longValue(), clientId); 
       Long id = logTransactionFileUpload(fileMetdataBean); 
       return null; 
      } 
      catch (Exception e) 
      { 
       String msg = "Inside JobRunnerServiceImpl.logClientFile - Unable to log client file"; 
       LOG.error(msg,e); 
       throw new RuntimeException(msg,e); 
      } 

     } 

     private Long logTransactionFileUpload(FileMetaDataBean bean) 
     { 
      return (Long)fileMetaDataDAO.save(bean); 
     } 


    } 

Мой боб:

@Entity 
    @Table(name="FILE_META_DATA", schema = "OAP_META_OWNER", uniqueConstraints = { 
      @UniqueConstraint(columnNames = "file_meta_data_id"), 
      }) 
    //@SequenceGenerator(name="file_meta_seq", sequenceName="file_meta_seq") 
    public class FileMetaDataBean implements Serializable 
    { 

     private long fileMetaDataId; 
     private Long fileType; 
     private String fileName; 
     private String originaFileName; 
     private Date receivedDt; 
     private Long recordCount; 
     private Long clientId; 

     public FileMetaDataBean(){} 

     public FileMetaDataBean(long fileMetaDataId, Long fileType, String fileName, String originaFileName, Date receivedDt, 
       long recordCount, long clientId) 
     { 
      super(); 
      this.fileMetaDataId = fileMetaDataId; 
      this.fileType = fileType; 
      this.fileName = fileName; 
      this.originaFileName = originaFileName; 
      this.receivedDt = receivedDt; 
      this.recordCount = recordCount; 
      this.clientId = clientId; 
     } 

     @Id 
    // @GeneratedValue(strategy = GenerationType.AUTO, generator = "file_meta_seq") 
     @Column(name = "file_meta_data_id", unique = true, nullable = false) 
     public long getFileMetaDataId() 
     { 
      return fileMetaDataId; 
     } 

     public void setFileMetaDataId(long fileMetaDataId) 
     { 
      this.fileMetaDataId = fileMetaDataId; 
     } 

     @Column(name = "file_type_id", unique = false, nullable = false) 
     public Long getFileType() 
     { 
      return fileType; 
     } 

     public void setFileType(Long fileType) 
     { 
      this.fileType = fileType; 
     } 

     @Column(name = "file_name", unique = false, nullable = false) 
     public String getFileName() 
     { 
      return fileName; 
     } 

     public void setFileName(String fileName) 
     { 
      this.fileName = fileName; 
     } 

     @Column(name = "original_file_name", unique = false, nullable = false) 
     public String getOriginaFileName() 
     { 
      return originaFileName; 
     } 

     public void setOriginaFileName(String originaFileName) 
     { 
      this.originaFileName = originaFileName; 
     } 

     @Column(name = "received_dt", unique = false, nullable = false) 
     public Date getReceivedDt() 
     { 
      return receivedDt; 
     } 

     public void setReceivedDt(Date receivedDt) 
     { 
      this.receivedDt = receivedDt; 
     } 

     @Column(name = "record_count", unique = false, nullable = false) 
     public Long getRecordCount() 
     { 
      return recordCount; 
     } 

     public void setRecordCount(Long recordCount) 
     { 
      this.recordCount = recordCount; 
     } 

     @Column(name = "client_id", unique = false, nullable = false)  
     public Long getClientId() 
     { 
      return clientId; 
     } 

     public void setClientId(Long clientId) 
     { 
      this.clientId = clientId; 
     } 

    } 

дао интерфейс

import java.io.Serializable; 
    import java.util.List; 
    import java.util.Map; 

    import org.hibernate.SessionFactory; 
    import org.springframework.transaction.annotation.Transactional; 

    public interface IGenericDAO< Entity extends Serializable, ID extends Serializable > 
    { 

     Entity getById(ID id); 

     List<Entity> getAll(); 

     List<Entity> getAll(String contraints); 

     List<Entity> search(Map<String, Object> parms); 

     ID save(Entity entity); 

     void saveOrUpdate(Entity entity); 

     void update(Entity entity); 

     void delete(Entity entity); 

     void deleteById(ID id); 

     void setSessionFactory(SessionFactory sessionFactory); 

     void setEntity(final Class clazz); 

    } 

дао осущ:

@SuppressWarnings(value = "unchecked") 
    public class GenericDAOImpl<Entity extends Serializable, ID extends Serializable> 
      implements IGenericDAO<Entity, ID> { 

     protected Class<Entity> clazz; 

     public GenericDAOImpl(Class<Entity> clazz) { 
      System.out.println(this.getClass().getSimpleName() + " called"); 
      this.clazz = clazz; 
     } 

     @Autowired 
     @Qualifier("sessionFactory") 
     protected SessionFactory sessionFactory; 

     @Override 
     public Entity getById(ID id) { 
      System.out.println("GenericHibernateDAO.getById called with id: " + id); 
      return (Entity) getCurrentSession().get(clazz, id); 
     } 

     @Override 
     public List<Entity> getAll() { 
      System.out.println("GenericHibernateDAO.getAll called"); 

      return getCurrentSession().createCriteria(clazz.getName()).list(); 


    //  return getCurrentSession().createQuery("from " + clazz.getName()).list(); 
     } 

     @Override 
     public List<Entity> getAll(String contraints) { 
      System.out.println("GenericHibernateDAO.getAll called. Constraint : " + contraints); 
      return getCurrentSession().createQuery("from " + clazz.getName() + " " + contraints).list(); 
     } 

     @Override 
     public List search(Map<String, Object> parms) { 
      Criteria criteria = getCurrentSession().createCriteria(clazz); 

      for (String field : parms.keySet()) { 
       criteria.add(Restrictions.ilike(field, parms.get(field))); 
      } 
      return criteria.list(); 
     } 

     @Override 
     public ID save(Entity entity) { 
      Serializable id = null; 
      try 
      { 
       id = getCurrentSession().save(entity); 
      } 
      catch(RuntimeException e) 
      { 
       throw e; 
      } 
    //  getCurrentSession().flush(); 
    //  getCurrentSession().getTransaction().commit(); 

      return (ID)id; 

     } 

     @Override 
     public void saveOrUpdate(Entity entity) { 
      getCurrentSession().saveOrUpdate(entity); 
      getCurrentSession().flush(); 
      getCurrentSession().getTransaction().commit(); 
     } 

     @Override 
     public void update(Entity entity) { 
      getCurrentSession().update(entity); 
      getCurrentSession().flush(); 
      getCurrentSession().getTransaction().commit(); 
     } 

     @Override 
     public void delete(Entity entity) { 
      getCurrentSession().delete(entity); 
      getCurrentSession().flush(); 
      getCurrentSession().getTransaction().commit(); 
     } 

     @Override 
     public void deleteById(ID id) { 
      delete(getById(id)); 
     } 

     protected Session getCurrentSession() { 

      // return sessionFactory.openSession(); 
      return sessionFactory.getCurrentSession(); 
     } 

     @Override 
     public void setSessionFactory(SessionFactory sessionFactory) { 
      this.sessionFactory = sessionFactory; 
     } 

     @Override 
     public void setEntity(final Class clazz) { 
      this.clazz = clazz; 
     } 

    } 
+0

Вы пытались переместить '@ Transactional' с уровня класса на уровень? Ожидаете ли вы, что при завершении выполнения 'logClientFile' должна быть запись в БД (видимая) до завершения метода' submitJob'? У меня также была проблема с тем же вопросом, когда я пытаюсь выполнить длинную задачу в одной транзакции. Вы можете получить 'id' bcoz, запись вставляется в БД, но поскольку ваша транзакция все еще продолжается, вы не можете видеть запись в БД. Вы добавили '@ Transactional' в класс, это означает, что все методы в этом классе находятся в транзакции. Проверьте выполнение БД после завершения выполнения вашей программы. – OO7

+0

Вы правы. Это вложенная транзакция и была отброшена назад, поскольку родитель имел исключение из «msgProducer.send (message, jmsConnectInfo)» в классе JobRunnerServiceImpl, в методе submitJob - после вставки db.Поэтому откат. Интересно, существует ли способ сохранить дочернюю транзакцию, даже если родительский сбой. – Patty

+0

Добавьте аннотацию '@ Transactional' к уровню метода и попробуйте с' распространение'. – OO7

ответ

1

Вы можете использовать

noRollbackFor

свойство транзакционных аннотаций что-то вроде, например, @Transactional(noRollbackFor=SendMsgFailureException.class). Вам нужно обработать исключение метода родительского вызова, для которого вы не хотите отката.

+0

пробовал с @Transactional (noRollbackFor = FileMetaDataBean.class) на уровне класса для класса JobRunnerServiceImpl. Это не работает. – Patty

+0

для вашего случая вам нужно поставить @Transactional на уровне метода, так как ваш метод будет бросать исключение, для которого вы бы хотели откатиться. Также «noRollbackFor» всегда должен быть для класса исключения, а не для вашего класса обслуживания. – mhasan

+0

Спасибо mhasan. Он работал после добавления @Transactional (noRollbackFor = RuntimeException.class) на уровне метода, где он получал исключение во время выполнения. – Patty

 Смежные вопросы

  • Нет связанных вопросов^_^