2014-09-30 54 views
0

后,我拿到代码:原子事务使用JDBC调用当Hibernate处理

@Override 
public void bulkInsert(Collection<SortingPlanData> data, SortingPlan plan) { 
    Session session = getEntityManager().unwrap(Session.class); 
    SessionFactoryImplementor sessionFactoryImplementation = (SessionFactoryImplementor) session 
      .getSessionFactory(); 
    ConnectionProvider connectionProvider = sessionFactoryImplementation 
      .getConnectionProvider(); 

    String sql = "insert into SORTING_PLAN_DATA (ACHEMINEMENT, ANCIEN_GROUPE_SERVICE_LABELS, BAG_ID, BARCODE_ID, CHRONOSERVICE, CODE_ROUTING, D_DEPOT_NUMBER, D_SORT, DELIVERY_STATION, DESCRIPTION, DESTINATION_PAYS_ALPHA2_ISO, DESTINATION_PAYS_ALPHA3_ISO, DESTINATION_PAYS_NUM_ISO," 
      + " DIST, GROUPE_SERVICE_LABELS, GROUPING_PRIORITY, LIVRAISON, O_SORT, ORIGINE_PAYS_ALPHA2_ISO, ROUTING_PLACES, S_SORT, SENDING_DATE, SERVICE_CODES, SITE_IATA, SORTING_PLAN_ID, TYPE_EXPORT, VILLE, ZIP_MAX, ZIP_MIN) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; 

    Transaction tx = session.getTransaction(); 

    final int batchSize = 500; 
    int count = 0; 

    try { 
     tx.begin(); 
     Connection con = connectionProvider.getConnection(); 
     PreparedStatement ps = con.prepareStatement(sql); 

     for (SortingPlanData spd : data) { 
      ps.setString(1, spd.getAcheminement()); 
      ps.setString(2, spd.getAncienGroupeServiceLabels()); 
      ps.setString(3, spd.getBagId()); 
      ps.setString(4, spd.getBarcodeId()); 
      ps.setString(5, spd.getChronoservice()); 
      ps.setString(6, spd.getCodeRouting()); 
      ps.setString(7, spd.getDDepotNumber()); 
      ps.setString(8, spd.getDSort()); 
      ps.setString(9, spd.getDeliveryStation()); 
      ps.setString(10, spd.getDescription()); 
      ps.setString(11, spd.getDestinationPaysAlpha2Iso()); 
      ps.setString(12, spd.getDestinationPaysAlpha3Iso()); 
      ps.setInt(13, spd.getDestinationPaysNumIso()); 
      ps.setString(14, spd.getDist()); 
      ps.setString(15, spd.getGroupeServiceLabels()); 
      ps.setString(16, spd.getGroupingPriority()); 
      ps.setString(17, spd.getLivraison()); 
      ps.setString(18, spd.getOSort()); 
      ps.setString(19, spd.getOriginePaysAlpha2Iso()); 
      ps.setString(20, spd.getRoutingPlaces()); 
      ps.setString(21, spd.getSSort()); 
      ps.setDate(22, new java.sql.Date(System.currentTimeMillis())); 
      ps.setString(23, spd.getServiceCodes()); 
      ps.setString(24, spd.getSiteIata()); 
      ps.setLong(25, plan.getId()); 
      ps.setString(26, spd.getTypeExport()); 
      ps.setString(27, spd.getVille()); 
      ps.setString(28, spd.getZipMin()); 
      ps.setString(29, spd.getZipMax()); 

      ps.addBatch(); 

      count++; 

      if (count % batchSize == 0) { 
       ps.executeBatch(); 
       LOGGER.info(count + " lines inserted do far in"); 
      } 
     } 

     ps.executeBatch(); // insert remaining records 
     ps.close(); 
     con.close(); 

    } catch (SQLException e) { 
     tx.rollback(); 
     throw new HibernateException(e.getMessage(), e.getCause()); 
    } 

    tx.commit(); 
} 

的bulkInsert方法是从本身标注有@Transactional一类叫,当然,我得到tx.begin()一个异常:

org.hibernate.TransactionException: nested transactions not supported 

问题是,我对如何获取现有的事务并将其传输到我的bulkInsert()方法不知道。任何线索?

我在一个Sybase 15.5数据库上使用Java 6,Hibernate 4,Spring 3.2.3。

+0

您正在变得复杂。使用一个'JdbcTemplate',它使用与你的'EntityManagerFactory'相同的'DataSource',它将自动参与同一个事务,接下来它将大大简化你的代码。 – 2014-09-30 18:05:12

回答

1

您正在使其复杂化,使用[JdbcTemplate][1],它使用与您的EntityManagerFactory相同的DataSource。这将获得当前连接并自动参与已经进行的事务。接下来会大大简化您的代码。

@Autowired 
private JdbcTemplate jdbcTemplate 

@Override 
public void bulkInsert(Collection<SortingPlanData> data, SortingPlan plan) { 
    String sql = "insert into SORTING_PLAN_DATA (ACHEMINEMENT, ANCIEN_GROUPE_SERVICE_LABELS, BAG_ID, BARCODE_ID, CHRONOSERVICE, CODE_ROUTING, D_DEPOT_NUMBER, D_SORT, DELIVERY_STATION, DESCRIPTION, DESTINATION_PAYS_ALPHA2_ISO, DESTINATION_PAYS_ALPHA3_ISO, DESTINATION_PAYS_NUM_ISO," 
      + " DIST, GROUPE_SERVICE_LABELS, GROUPING_PRIORITY, LIVRAISON, O_SORT, ORIGINE_PAYS_ALPHA2_ISO, ROUTING_PLACES, S_SORT, SENDING_DATE, SERVICE_CODES, SITE_IATA, SORTING_PLAN_ID, TYPE_EXPORT, VILLE, ZIP_MAX, ZIP_MIN) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; 

    jdbcTemplate.batchUpdate(sql, data, 500, new ParameterizedPreparedStatementSetter<SortingPlanData>() { 
     public void setValues(PreparedStatement ps, SortingPlanData spd) throws SQLException { 
      ps.setString(1, spd.getAcheminement()); 
      ps.setString(2, spd.getAncienGroupeServiceLabels()); 
      ps.setString(3, spd.getBagId()); 
      ps.setString(4, spd.getBarcodeId()); 
      ps.setString(5, spd.getChronoservice()); 
      ps.setString(6, spd.getCodeRouting()); 
      ps.setString(7, spd.getDDepotNumber()); 
      ps.setString(8, spd.getDSort()); 
      ps.setString(9, spd.getDeliveryStation()); 
      ps.setString(10, spd.getDescription()); 
      ps.setString(11, spd.getDestinationPaysAlpha2Iso()); 
      ps.setString(12, spd.getDestinationPaysAlpha3Iso()); 
      ps.setInt(13, spd.getDestinationPaysNumIso()); 
      ps.setString(14, spd.getDist()); 
      ps.setString(15, spd.getGroupeServiceLabels()); 
      ps.setString(16, spd.getGroupingPriority()); 
      ps.setString(17, spd.getLivraison()); 
      ps.setString(18, spd.getOSort()); 
      ps.setString(19, spd.getOriginePaysAlpha2Iso()); 
      ps.setString(20, spd.getRoutingPlaces()); 
      ps.setString(21, spd.getSSort()); 
      ps.setDate(22, new java.sql.Date(System.currentTimeMillis())); 
      ps.setString(23, spd.getServiceCodes()); 
      ps.setString(24, spd.getSiteIata()); 
      ps.setLong(25, plan.getId()); 
      ps.setString(26, spd.getTypeExport()); 
      ps.setString(27, spd.getVille()); 
      ps.setString(28, spd.getZipMin()); 
      ps.setString(29, spd.getZipMax()); 
     } 
    }); 
} 
+0

谢谢,那就是我一直在寻找的。 – 2014-10-01 11:59:13

+0

事实上,当插入大量的线(超过100000)时,我遇到了问题。我的Sybase ASE RDBMS正在抗议它没有可用的锁,并且没有插入任何东西。你知道这件事吗? – 2014-10-09 15:16:03

+0

其实我不知道,确保它在单个事务下执行,并且在优化阅读时可能会做某些事情。我想与Sybase合作(我已经使用了12年左右)来帮助你。 – 2014-10-10 08:41:46