Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring mvc Spring JPA回滚不工作_Spring Mvc_Spring Data Jpa_Spring Transactions_Transactional - Fatal编程技术网

Spring mvc Spring JPA回滚不工作

Spring mvc Spring JPA回滚不工作,spring-mvc,spring-data-jpa,spring-transactions,transactional,Spring Mvc,Spring Data Jpa,Spring Transactions,Transactional,我的web服务写入两个MySQL表(一个接一个;依赖于外键)。我已经让我的服务方法[upload(…])抛出一个强制异常,只是为了检查回滚功能。即使抛出异常,记录也会保存在文件存储表(第一个表)中。请帮我弄清楚出了什么问题。另外,如果任何上下文配置不正确,请告诉我。谢谢 文件:root-context.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/s

我的web服务写入两个MySQL表(一个接一个;依赖于外键)。我已经让我的服务方法[upload(…])抛出一个强制异常,只是为了检查回滚功能。即使抛出异常,记录也会保存在文件存储表(第一个表)中。请帮我弄清楚出了什么问题。另外,如果任何上下文配置不正确,请告诉我。谢谢

文件:root-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">

    <!-- Root Context: defines shared resources visible to all other web components -->

    <!-- Database -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/app?autoReconnect=true"/>
        <property name="username" value="${datasource.username}"/>
        <property name="password" value="${datasource.password}"/>
    </bean>

    <!-- JPA Vendor Adapter -->
    <bean id="jpaVendorAdapter"
        class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
        <property name="showSql" value="true" />
        <property name="generateDdl" value="true" />
        <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect"></property>
    </bean>

    <!-- Entity Manager Factory -->
    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
        <property name="packagesToScan" value="com.app.test.persistence" />
    </bean>

    <!-- Transaction Manager -->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

    <!-- Detect @Transactional -->
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />

    <!-- JPA Repositories -->
    <jpa:repositories base-package="com.app.test.repository"/>

    <!-- JASYPT Configuration -->
    <bean id="configurationEncryptor" class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor">
        <property name="algorithm">
            <value>PBEWithMD5AndDES</value>
        </property>
        <property name="password">
            <value>com.app.test</value>
        </property>
    </bean>

    <bean id="propertyConfigurer" class="org.jasypt.spring.properties.EncryptablePropertyPlaceholderConfigurer">
        <constructor-arg ref="configurationEncryptor" />
        <property name="locations">
            <list>
                <value>classpath:runtime.properties</value>
            </list>
        </property>
    </bean>

    <!-- Properties Util -->
    <bean id="propertiesUtil" class="com.app.test.util.PropertiesUtil">
        <property name="location" value="classpath:app.properties"></property>
    </bean>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

    <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->

    <!-- Detect @Controller -->
    <annotation-driven />

    <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
    <resources mapping="/**" location="/WEB-INF/" />

    <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".jsp" />
    </beans:bean>

    <context:component-scan base-package="com.app.test" />

    <beans:bean id="jsonMapper" class="com.fasterxml.jackson.databind.ObjectMapper"></beans:bean>
</beans:beans>
文件:FileStore.Java(Entity-2)

文件:filestoreserviceinpl.java

package com.app.test.service.impl;

@Service
@Transactional
public class FileStoreServiceImpl implements FileStoreService {
    @Autowired
    private FileStoreDAO fileStoreDAO;

    @Autowired
    private FileDAO fileDAO;

    private static final Integer ID_LENGTH = 16;

    @Override
    @Transactional(rollbackFor={Exception.class, RuntimeException.class})
    public String upload(UploadRequest jRequest, String uploadedFrom) throws Exception {
        //String fileKey = null;

        try {
            //get the file content from packet
            String fileContent = jRequest.getContent();

            //compute checksum
            String checksum = DigestUtils.sha1Hex(fileContent);

            //check if similar file exists
            if (!fileStoreDAO.checksumExists(checksum)) {
                //create file store object
                FileStore fStore = new FileStore();
                fStore.setUniqueKey(RandomUtil.getRandomKey(checksum, ID_LENGTH));
                fStore.setChecksum(checksum);
                fStore.setUploadedOn(new Date());
                fStore.setUploadedFrom(uploadedFrom);
                fileStoreDAO.saveFileStore(fStore);

                //create file object
                File file = new File();
                file.setFileStore(fStore);
                file.setContent(fileContent.getBytes());

                throw new Exception("Forced exception"); //Expecting Spring JPA to rollback the transaction; but not happenning :(

                /*fileDAO.saveFile(file);
            } else {
                throw new Exception("Similar file already exists.");
            }
        } catch (Exception e) {
            throw e;
        }

        //return fileKey;
    }

}
文件:FileController.java

package com.app.test.controller;

@Controller
public class FileStoreController {
    @Autowired
    FileStoreService fileStoreService;

    @Autowired
    ObjectMapper jsonMapper;

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public ModelAndView processIndex(HttpServletRequest request, HttpServletResponse response) {
        return new ModelAndView("index", null);
    }

    private String retrieveData(HttpServletRequest request) {
        StringBuffer jBuffer = new StringBuffer();
        String line = null;

        try {
            BufferedReader reader = request.getReader();
            while ((line = reader.readLine()) != null)
                jBuffer.append(line);
        } catch (Exception e) {
            return null;
        }

        return jBuffer.toString();
    }

    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    @ResponseBody
    public String processUpload(HttpServletRequest request, HttpServletResponse response) {
        UploadResponse jResponse = new UploadResponse();

        try {
            //retrieve request packet
            String pData = retrieveData(request);
            String fromAddress = request.getRemoteAddr();

            if (null != pData && !("".equals(pData))) {
                UploadRequest jRequest = jsonMapper.readValue(pData, UploadRequest.class);
                String fileKey = fileStoreService.upload(jRequest, fromAddress);

                UploadSuccess success = new UploadSuccess();
                success.setFileId(fileKey);
                success.setMessage("File uploaded successfully");
                jResponse.setSuccess(success);
            } else {
                Error error = new Error();
                error.setMessage("Packet is empty.");
                jResponse.setError(error);
            }
        } catch (Exception e) {
            Error error = new Error();
            error.setMessage(e.getMessage());
            jResponse.setError(error);
        }

        try {
            return jsonMapper.writeValueAsString(jResponse);
        } catch (Exception ex) {
            return "Fatal exception occurred while processing upload request.";
        }
    }
}

您必须在根上下文文件上扫描服务,根上下文文件是您的应用程序上下文,但不在servlet上下文中,请参阅本文以了解有关

扫描
根上下文上的服务

<context:component-scan
        base-package="com.app.test.service.impl"/>
默认情况下,spring transactionnal将回滚
RuntimeException
,无需将它们添加到回滚类列表中:

@Transactional(rollbackFor=..)
编辑 Spring的事务管理仅针对未检查的异常回滚事务(RuntimeException)


谢谢你,影子。不幸的是,这些改变不起作用。服务仍在提交表中的数据。@madguy您能否从类级别删除
@Transactionnal
,并将其保留在方法上,然后重试againIt works。已从类级别删除“@Transactional”,并使该方法引发RuntimeException而不是Exception。交易正在回滚。
package com.app.test.service.impl;

@Service
@Transactional
public class FileStoreServiceImpl implements FileStoreService {
    @Autowired
    private FileStoreDAO fileStoreDAO;

    @Autowired
    private FileDAO fileDAO;

    private static final Integer ID_LENGTH = 16;

    @Override
    @Transactional(rollbackFor={Exception.class, RuntimeException.class})
    public String upload(UploadRequest jRequest, String uploadedFrom) throws Exception {
        //String fileKey = null;

        try {
            //get the file content from packet
            String fileContent = jRequest.getContent();

            //compute checksum
            String checksum = DigestUtils.sha1Hex(fileContent);

            //check if similar file exists
            if (!fileStoreDAO.checksumExists(checksum)) {
                //create file store object
                FileStore fStore = new FileStore();
                fStore.setUniqueKey(RandomUtil.getRandomKey(checksum, ID_LENGTH));
                fStore.setChecksum(checksum);
                fStore.setUploadedOn(new Date());
                fStore.setUploadedFrom(uploadedFrom);
                fileStoreDAO.saveFileStore(fStore);

                //create file object
                File file = new File();
                file.setFileStore(fStore);
                file.setContent(fileContent.getBytes());

                throw new Exception("Forced exception"); //Expecting Spring JPA to rollback the transaction; but not happenning :(

                /*fileDAO.saveFile(file);
            } else {
                throw new Exception("Similar file already exists.");
            }
        } catch (Exception e) {
            throw e;
        }

        //return fileKey;
    }

}
package com.app.test.controller;

@Controller
public class FileStoreController {
    @Autowired
    FileStoreService fileStoreService;

    @Autowired
    ObjectMapper jsonMapper;

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public ModelAndView processIndex(HttpServletRequest request, HttpServletResponse response) {
        return new ModelAndView("index", null);
    }

    private String retrieveData(HttpServletRequest request) {
        StringBuffer jBuffer = new StringBuffer();
        String line = null;

        try {
            BufferedReader reader = request.getReader();
            while ((line = reader.readLine()) != null)
                jBuffer.append(line);
        } catch (Exception e) {
            return null;
        }

        return jBuffer.toString();
    }

    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    @ResponseBody
    public String processUpload(HttpServletRequest request, HttpServletResponse response) {
        UploadResponse jResponse = new UploadResponse();

        try {
            //retrieve request packet
            String pData = retrieveData(request);
            String fromAddress = request.getRemoteAddr();

            if (null != pData && !("".equals(pData))) {
                UploadRequest jRequest = jsonMapper.readValue(pData, UploadRequest.class);
                String fileKey = fileStoreService.upload(jRequest, fromAddress);

                UploadSuccess success = new UploadSuccess();
                success.setFileId(fileKey);
                success.setMessage("File uploaded successfully");
                jResponse.setSuccess(success);
            } else {
                Error error = new Error();
                error.setMessage("Packet is empty.");
                jResponse.setError(error);
            }
        } catch (Exception e) {
            Error error = new Error();
            error.setMessage(e.getMessage());
            jResponse.setError(error);
        }

        try {
            return jsonMapper.writeValueAsString(jResponse);
        } catch (Exception ex) {
            return "Fatal exception occurred while processing upload request.";
        }
    }
}
<context:component-scan
        base-package="com.app.test.service.impl"/>
<context:component-scan
        base-package="com.app.test.controller"/>
@Transactional(rollbackFor=..)
throw new RuntimeException("forced exception");