Hibernate进程后使用JDBC调用时的原子事务

时间:2014-09-30 15:56:49

标签: java spring hibernate jdbc transactions

我得到了那段代码:

@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。

1 个答案:

答案 0 :(得分:1)

您正在使用复杂的方法,使用与[JdbcTemplate][1]使用相同DataSource的{​​{1}}。这将获得当前连接并自动参与已在进行的交易。接下来,它将大大简化您的代码。

EntityManagerFactory