【问题标题】:Spring MVC - JDBCTemplate - TransactionalSpring MVC - JDBCTemplate - 事务性
【发布时间】:2014-09-07 08:23:23
【问题描述】:

我正在尝试使用带有事务保存的 JDBCTemplate 的 SPRING MVC。当它是事务性的,当保存在数据库中时出现任何错误时,我希望它能够回滚所有数据库操作。在这里,我考虑了 2 个表,并在具有注释 @Transactional 的单个方法中将数据保存在两个表中。我故意发送比 db 中为字段声明的大小更多的文本,以查看第一个表数据是否正在回滚,但它保存在第一个表中(没有回滚)。请帮我解决问题。

Beans.xml

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

                    <!-- Initialization for TransactionManager -->  
                   <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
                  <property name="dataSource" ref="dataSource"></property>       
               </bean>  

               <!-- Initialization for data source -->
               <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/test"/>
                  <property name="username" value="root"/>
                      <property name="password" value="root"/>
               </bean>

               <!-- Definition for studentJDBCTemplate bean -->
               <bean id="studentJDBCTemplate" class="com.springjdbctemplate.StudentJDBCTemplate">
                  <property name="dataSource"  ref="dataSource" />    
               </bean>

            </beans>

StdentJDBC 模板:

    public class StudentJDBCTemplate implements StudentDAO {

        private DataSource dataSource;
        private JdbcTemplate jdbcTemplate;

        @Override
        public void setDataSource(DataSource ds) {
            this.dataSource = ds;
            this.jdbcTemplate = new JdbcTemplate(this.dataSource);
        }

        @Transactional
        @Override
        public void create(String name, Integer age, int id, String address) {
            String SQL = "insert into springstudent (name, age, id) values (?, ?, ?)";
                jdbcTemplate.update(SQL, name, age, id);
            System.out.println("Created Record Name = " + name + " Age = " + age + " id = " + id);

            SQL = "insert into springaddress (name, address) values (?, ?)";
            jdbcTemplate.update(SQL, name, address);
            System.out.println("Created Record Name = " + name + " address = " + address);

        }

        @Override
        public Student getStudent(Integer id) {
            return null;
        }

        @Override
        public List<Student> listStudents() {
            String SQL = "select * from springstudent";
            List<Student> students = jdbcTemplate.query(SQL, new StudentMapper1());
            return students;
        }

web.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"        xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee         http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
      <display-name>SpringSampleApplications</display-name>

       <servlet>
            <servlet-name>welcome</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>welcome</servlet-name>
            <url-pattern>/</url-pattern>
         </servlet-mapping>

      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
    </web-app>

主应用程序:

    public static void main(String[] args) {
            ApplicationContext context = 
                     new ClassPathXmlApplicationContext("Beans.xml");

              StudentJDBCTemplate studentJDBCTemplate = (StudentJDBCTemplate)context.getBean("studentJDBCTemplate");

            System.out.println("------Records Creation--------" );
              studentJDBCTemplate.create("Zara", 11, 1, "addr1");
              studentJDBCTemplate.create("Nuha", 2, 2, "addr2");
              studentJDBCTemplate.create("Ayan", 15, 3, "addr3addr1addr1");

              System.out.println("------Listing Multiple Records--------" );
              List<Student> students = studentJDBCTemplate.listStudents();
              for (Student record : students) {
                 System.out.print("ID : " + record.getId() );
                 System.out.print(", Name : " + record.getName() );
                 System.out.println(", Age : " + record.getAge());
              }

请帮助我我错过了什么......谢谢sss

【问题讨论】:

  • 检查你用的是javax.transaction.Transactional还是org.springframework.transaction.annotation.Transactional。
  • @Dmytro,我正在使用 import org.springframework.transaction.annotation.Transactional;在我的代码中

标签: spring-mvc jdbc transactions


【解决方案1】:

确保您的数据源未设置为“autoCommit=true”。

您需要在 Beans.xml 中添加类似的内容:

<tx:annotation-driven transaction-manager="transactionManager" />

【讨论】:

  • 您好,感谢您的回答——但我使用的驱动程序是“class="org.springframework.jdbc.datasource.DriverManagerDataSource"。当我尝试使用 defaultAutoCommit 属性时,它会抛出一个错误该属性不受支持。我尝试以另一种方式使用 -- try { this.jdbcTemplate.getDataSource().getConnection().setAutoCommit(false); } catch (SQLException e) { // TODO 自动生成的 catch 块 e。 printStackTrace(); } 这不会引发任何错误,但第一个表数据正在保存:(
  • 我猜 DriverManagerDataSource 自己会做 defaultAutoCommit=false 。但我已经编辑了我的答案 - 您需要启用注释事务。
  • with annotation-driven -- 运行代码时出现错误 ERROR: org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from class path resource [Beans.xml];嵌套异常是 java.lang.AbstractMethodError: org.springframework.beans.factory.xml.AbstractBeanDefinitionParser.parseInternal(Lorg/w3c/dom/Element;Lorg/springframework/beans/factory/xml/ParserContext;) 如果我删除该行注释驱动,代码正在运行(但事务性无法实现)。
  • 这是完整的堆栈跟踪吗?
  • 我无法在此处粘贴整个跟踪。线程“main”中的异常 org.springframework.beans.factory.BeanDefinitionStoreException:从类路径资源 [Beans.xml] 解析 XML 文档时出现意外异常;嵌套异常是 java.lang.AbstractMethodError: org.springframework.beans.factory.xml.AbstractBeanDefinitionParser.parseInternal(Lorg/w3c/dom/Element;Lorg/springframework/beans/factory/xml/ParserContext;)Lorg/springframework/beans/工厂/支持/AbstractBeanDefinition;在 org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.ja)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-25
  • 2019-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多