Я работаю над проектом Spring-MVC, в котором я вызываю определенные методы с аннотацией @Transactional(readOnly=true)
. К сожалению, даже после этого содержимое базы данных обновляется. Не знаю, как это сделать. Что я делаю не так? У нас была эта ошибка в течение некоторого времени, просто не знали, что это вызвало изменения в базе данных, поскольку мы полностью игнорировали ее, учитывая, что в аннотации конкретно говорится, что она не редактируется, но мы были так неправы.Весна, Спящий режим: Транзакция только для чтения равна true не работает
Свойства проекта:
<properties>
<java-version>1.8</java-version>
<org.springframework-version>4.1.6.RELEASE</org.springframework-version>
<org.aspectj-version>1.7.4</org.aspectj-version>
<org.slf4j-version>1.7.5</org.slf4j-version>
<hibernate.version>4.3.9.Final</hibernate.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<springsecurity.version>4.0.1.RELEASE</springsecurity.version>
<spring-platform.version>1.1.3.RELEASE</spring-platform.version>
<jetty.version>9.2.9.v20150224</jetty.version>
</properties>
<parent>
<groupId>io.spring.platform</groupId>
<artifactId>platform-bom</artifactId>
<version>1.1.3.RELEASE</version>
<relativePath />
</parent>
Код:
@Override
public byte[] createExcelSheetOutOfCanvas(int canvasId) {
String str = new BigInteger(130, random).toString(32);
List<GroupSection> groupSectionList = this.groupSectionService.listGroupSectionByCanvasid(canvasId, false);
try {
Workbook workbook = new HSSFWorkbook();
Sheet sheet = workbook.createSheet();
int rowCount = 0;
Row initialRow = sheet.createRow(rowCount);
writeNames(initialRow);
for (GroupSection groupSection : groupSectionList) {
rowCount++;
Row row = sheet.createRow(++rowCount);
writeSectionRow(row, groupSection.getMsectionname());
List<GroupNotes> groupNotesList = this.groupNotesDAO.listGroupNotesBySectionId(groupSection.getMsectionid());
for (GroupNotes note : groupNotesList) {
row = sheet.createRow(++rowCount);
writeBook(note, row);
}
}
try (FileOutputStream outputStream = new FileOutputStream("/home/deploy/excel/" + str + ".xls")) {
workbook.write(outputStream);
Path path = Paths.get("/home/deploy/excel/" + str + ".xls");
return Files.readAllBytes(path);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
GroupSectionServiceImpl:
@Service
@Transactional
public class GroupSectionServiceImpl implements GroupSectionService {
private final GroupSectionDAO groupSectionDAO;
@Autowired
public GroupSectionServiceImpl(GroupSectionDAO groupSectionDAO) {
this.groupSectionDAO = groupSectionDAO;
}
@Override
@org.springframework.transaction.annotation.Transactional(readOnly = true)
public List<GroupSection> listGroupSectionByCanvasid(int mcanvasid, boolean masterSectionFlag) {
List<GroupSection> groupSectionList = this.groupSectionDAO.listGroupSectionByCanvasid(mcanvasid);
// Other method code
}
GroupSectionDAOImpl:
@Repository
@Transactional
public class GroupSectionDAOImpl implements GroupSectionDAO {
private final SessionFactory sessionFactory;
@Autowired
public GroupSectionDAOImpl(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Override
@Transactional(readOnly = true)
public List<GroupSection> listGroupSectionByCanvasid(int mcanvasid) {
Session session = this.sessionFactory.getCurrentSession();
org.hibernate.Query query = session.createQuery("From GroupSection as msection where " +
"msection.currentcanvas.mcanvasid=:mcanvasid and msection.sectionDisabled=false and msection.sectionInActive=false");
query.setParameter("mcanvasid", mcanvasid);
return query.list();
}
}
Даже, в конце концов, это readOnly = true. Как это происходит, когда я звоню в метод createTheExcel, значения из базы данных перезаписываются.
метод управления:
@RequestMapping(value = "/downloadexcel/{canvasid}")
public void downloadExcelSheet(@PathVariable("canvasid") int canvasId, HttpServletResponse response) {
try {
response.setContentType("application/octet-stream");
GroupCanvas groupCanvas = this.groupCanvasService.getCanvasById(canvasId);
if (!(groupCanvas == null)) {
byte[] excelSheet = this.groupNotesService.createExcelSheetOutOfCanvas(canvasId);
response.setHeader("Content-Disposition", "attachment; filename=\"" + groupCanvas.getMcanvasname() + ".xls" + "\"");
response.setContentLength(excelSheet.length);
FileCopyUtils.copy(excelSheet, response.getOutputStream());
response.flushBuffer();
}
} catch (IOException e) {
e.printStackTrace();
}
}
Почему бы это. После завершения транзакции readonly не эффективен. И если уже была текущая (неточно) транзакция, часть readonly игнорируется. –
@ M.Deinum: Но я не вызываю код для обновления значений, я только вызываю код, чтобы перечислять разделы, как вы можете видеть из метода DAO. –
Если вы меняете вещи, пока вы находитесь в транзакции, они автоматически сохраняются. Вам не нужно явно обращаться к коду доступа к данным для управляемых объектов. –