Я работаю над корпоративным веб-приложением, в котором пользователи могут создавать и распечатывать PDF-файлы с помощью API iText 1.3. В последнее время я столкнулся с большой проблемой параллелизма, которая отображает неправильные данные для пользователя, другими словами, он отображает те же данные длявсе пользователи.
сценарий состоит в создании файла PDF более чем одним пользователем одновременно, вот метод вызова:
public PDFFile generate(final long cartId, final FicheClient ficheClient) {
PDFFile result = null;
Set<CartOperation> opeToPrint = new HashSet<CartOperation>();
Set<CartPostage> postToPrint = new HashSet<CartPostage>();
Set<CartProduct> prodToPrint = new HashSet<CartProduct>();
this.init();
cart = cart.get(cartId);
if (cart.getOperations() != null) {
for (CartOperation ope : cart.getOperations()) {
if (ope.getEntryState() == 0) {
opeToPrint.add(ope);
}
}
cart.setOperations(opeToPrint);
}
if (cart.getPostages() != null) {
for (CartPostageED post : cart.getPostages()) {
if (post.getEntryState() == 0) {
postToPrint.add(post);
}
}
cart.setPostages(postToPrint);
}
if (cart.getProducts() != null) {
for (CartProduct prod : cart.getProducts()) {
if (prod.getState() == 0) {
prodToPrint.add(prod);
}
}
cart.setProducts(prodToPrint);
}
address = address.findBySiteIdAndAddressTypeCode(cart
.getSite().getSiteId(), AddressTypeEnum.GEO
.getCode());
phone = phone.findBySiteIdAndPhoneTypeCode(cart.getSite()
.getSiteId(), PhoneTypeEnum.STANDARD.getCode());
// Récupération des taux de TVA
vatLevels = this.findVatLevels(cart.getSite().getRegCode());
if (ficheClient != null) {
result = super.generateInternal(ficheClient);
}
return result;
}
После проверки всехкод, который я подозреваю, что PdfWriter.getInstance (doc, baos);является одноэлементным и не синхронизируется, за исключением того, что я не нашел подозрительного кода, который мог бы вызвать это, вот метод
protected PDFFile generateInternal(final T data) {
PDFFile result = null;
final String methodName = "generate";
final Document doc = this.createDocument();
final CustomDocument tmpDoc = (CustomDocument) this.createDocument();
tmpDoc.setMock(true);
this.updateDocumentMargins(tmpDoc);
final ByteArrayOutputStream tmpBaos = new ByteArrayOutputStream();
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
FontFactory.defaultEmbedding = this.getFontEmbedding();
// Ouverture du document
synchronized (PdfWriter.getInstance(doc, baos)) {
final PdfWriter writer1 = PdfWriter.getInstance(doc, new
FileOutputStream(new File("C:/bordereau de vente"+i+".pdf")));
tmpWriter.setViewerPreferences(PdfWriter.PageLayoutSinglePage);
this.buildMetadata(tmpDoc, tmpWriter, data);
tmpDoc.open();
this.buildDocument(tmpDoc, tmpWriter, data);
// Fermeture du stream et du document.
tmpBaos.flush();
tmpBaos.close();
tmpDoc.close();
final PdfReader readerTemp = new PdfReader(tmpBaos.toByteArray());
final int nbPages = readerTemp.getNumberOfPages();
this.updateDocumentMargins(doc);
final PdfWriter writer = PdfWriter.getInstance(doc, baos);
writer.setViewerPreferences(PdfWriter.PageLayoutSinglePage);
this.buildMetadata(doc, writer, data);
doc.open();
this.addPageEvent(writer, nbPages);
this.buildDocument(doc, writer, data);
// Fermeture du stream et du document.
baos.flush();
baos.close();
doc.close();
result = new PDFFile(getPdfTypeEnum(), getDate());
result.setFileName(this.fileName);
result.setFileContent(baos.toByteArray());
} catch (IOException ioe) {
LOGGER.error(RGPLogPhaseEnum.ACTION, null, null, methodName,
RGPLogEtapeEnum.PHASE_ENCOURS, "Erreur lors de la lecture du
fichier PDF.");
ioe.printStackTrace();
} catch (DocumentException e) {
LOGGER.error(RGPLogPhaseEnum.ACTION, null, null, methodName,
RGPLogEtapeEnum.PHASE_ENCOURS, "Erreur lors de la création du fichier PDF.");
e.printStackTrace();
} finally {
if (doc.isOpen()) {
doc.close();
}
try {
baos.close();
} catch (IOException ioe) {
System.out.println();
LOGGER.error(RGPLogPhaseEnum.ACTION, null, null, methodName,
RGPLogEtapeEnum.PHASE_ENCOURS,
"Erreur lors de la fermeture du document PDF généré.");
}
}
return result;
}
Когда я вошел в систему с разными пользователями на одном сервере, вВ режиме отладки я установил точку останова в этой строке final PdfWriter writer = PdfWriter.getInstance (документ, новый FileOutputStream (новый файл ("C: / bordereau" + i + ". pdf"))); Когда ясработало первое действие (user1) сгенерированный файл содержит данные второго, что означает, что возвращаемый объект PdfWriter.getInstance (doc, baos); не синхронизирован, я добавил ключевое слово Synchronized atметод и уровень блока, но он не работает.
Почему объект не блокируется, когда он вызывается первым пользователем? я что-то упустил?