spring事务小案例

【该方法有缺陷,解决问题的版本在最后】

如果需要哪个方法用到事务,需要把这个方法所在类交给spring管理

可以把这个方法放进已经被spring管理的dao内

(@Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)

(@Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=false))

<bean name="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager" >
<property name="sessionFactory" ref="sessionFactory" ></property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />

WebDao.java

package dao;

import org.hibernate.SessionFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.orm.hibernate4.HibernateTemplate;
import org.springframework.orm.hibernate4.support.HibernateDaoSupport;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import bean.bean2;
@Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=false)
public class WebDao extends HibernateDaoSupport {
    
    public  WebDao() {
        System.out.println("dao");
    }
    
    public void save(bean2 bean2) {
        System.out.println(bean2);
        HibernateTemplate hibernateTemplate=  this.getHibernateTemplate();
        System.out.println("hibernateTemplate:"+hibernateTemplate);
        getHibernateTemplate().setCheckWriteOperations(false);
       this.getHibernateTemplate().save(bean2);    
    
       System.out.println("保存成功!");
       
    }
    
    public void test(bean2 bean2,bean2 bean3) {
        System.out.println(bean2);
        getHibernateTemplate().setCheckWriteOperations(false);
       this.getHibernateTemplate().save(bean2);    
    
       System.out.println("bean2保存成功!");
 
       System.out.println(bean3);
        getHibernateTemplate().setCheckWriteOperations(false);
      this.getHibernateTemplate().save(bean3);    
      
       //--------空指针异常
        int arr[] = { 1 };
        System.out.println(arr[10]);
        
        
      System.out.println("bean3保存成功!");
       
    }
    
}

aaplicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop" 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-4.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="jdbcUrl" value="jdbc:mysql:///test"></property>
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>

<!--事务模块(不使用注解的事务) begin-->
    <!-- 核心事务管理器 -->
    <bean name="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager" >
        <property name="sessionFactory" ref="sessionFactory" ></property>
    </bean>
    <tx:annotation-driven transaction-manager="transactionManager"/>
    <!-- 配置通知 -->
     <tx:advice id="txAdvice" transaction-manager="transactionManager" >
        <tx:attributes>
            <tx:method name="save*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
            <tx:method name="persist*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
            <tx:method name="update*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
            <tx:method name="modify*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
            <tx:method name="delete*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
            <tx:method name="remove*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
            <tx:method name="get*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true" />
            <tx:method name="find*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true" />
            <tx:method name="*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
        </tx:attributes>
    </tx:advice> 
    <!-- 配置将通知织入目标对象
    配置切点
    配置切面 -->

    
    <!--事务模块(不使用注解的事务) end -->
    <!-- ========================================================================================= -->
    <!-- 开启注解事务
    <tx:annotation-driven transaction-manager="transactionManager" />
     -->
    <!-- 将SessionFactory配置到spring容器中 -->
    <!-- 加载配置方案1:仍然使用外部的hibernate.cfg.xml配置信息 -->
    <!-- <bean name="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" >
        <property name="configLocation" value="classpath:hibernate.cfg.xml" ></property>
    </bean> -->

<bean name="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>

        <property name="hibernateProperties">
            <props>
                <!--  必选配置 -->
                <prop key="hibernate.connection.driver_class" >com.mysql.jdbc.Driver</prop>
                <prop key="hibernate.connection.url" >jdbc:mysql:///test</prop>
                <prop key="hibernate.connection.username" >root</prop>
                <prop key="hibernate.connection.password" >root</prop> 
                
                <!--  可选配置 -->
                <prop key="hibernate.dialect" >org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql" >true</prop>
                <prop key="hibernate.format_sql" >true</prop>
                <prop key="hibernate.hbm2ddl.auto" >update</prop>
            </props>
        </property>
        <!-- 引入orm元数据,指定orm元数据所在的包路径,spring会自动读取包中的所有配置 -->
        <property name="mappingDirectoryLocations" value="classpath:" ></property> 
        
        
    </bean>
    
<bean name="bean1" class="bean.bean1"></bean>
    <bean name="bean2" class="bean.bean2">
    <property name="bean1" ref="bean1"></property>
    <property name="name" value="test"></property>
    </bean>
    <bean name="beanDao" class="dao.WebDao">
    <property name="sessionFactory" ref ="sessionFactory">
</property></bean>
    
</beans>

在xml配置文件中开启注解

测试类TransTest.java中的主函数

    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext(
                "applicationContext.xml");
        WebDao dao = (WebDao) ac.getBean("beanDao");
        System.out.println(".........");
        
        bean2 bean2 = (bean2) ac.getBean("bean2");
        bean2.setName("事务测试1");
        bean2 bean3 = (bean2) ac.getBean("bean2");
        bean3.setName("事务测试2");
        System.out.println(".........");
        dao.test(bean2, bean3);
        
    }

运行后,数据库内不会插入数据,而且自增长的id会跳过这个数字

 

 

【无异常,正常插入两条数据的事务】

WebDao.java中的方法(修改后)

保存完第一个bean后要使用clear()方法清除缓存

    public void test(bean2 bean2,bean2 bean3) {
        System.out.println(bean2);
        getHibernateTemplate().setCheckWriteOperations(false);
       this.getHibernateTemplate().save(bean2);    
     
       System.out.println("bean2保存成功!");
 
       this.getHibernateTemplate().clear();
       System.out.println(bean3);
        getHibernateTemplate().setCheckWriteOperations(false);
      this.getHibernateTemplate().save(bean3);    

       //--------空指针异常
//        int arr[] = { 1 };
//        System.out.println(arr[10]);
        
      System.out.println("bean3保存成功!");
       
    }

TransTest.java中的主函数(修改后)

public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext(
                "applicationContext.xml");
        WebDao dao = (WebDao) ac.getBean("beanDao");
        System.out.println(".........");
        
        //bean2 bean2 = new bean2("123",1);
        bean2 bean2 = (bean2) ac.getBean("bean2");
        bean2.setName("事务测试1");
        bean2 bean3 = new bean2("123",1);
        bean3.setName("事务测试2");
        System.out.println(".........");
        dao.test(bean2, bean3);
        
    }

一个注意的点,把bean交给spring管理后,默认会有一个无参构造函数,如果自己后来又添加了有参构造,还需要自己补上一个无参构造

bean2.java(修改后)

package bean;

public class bean2 {
    String name="0";
    int id=1;

public bean2() {
    }
public bean2(String name, int id) {
        super();
        this.name = name;
        this.id = id;
    }
public void setBean1(bean1 bean1){
    System.out.println("bean2注入bean1:"+bean1);
    this.name=bean1.getName();
}
public void setName(String name) {
    this.name = name;
    System.out.println("bean2修改name:"+name);
}
public String getName() {
    return name;
}
public void setId(int id) {
    System.out.println("bean2setid");
    this.id = id;
}
public int getId() {
    return id;
}
@Override
public String toString() {
    return "bean2 [name=" + name + "]";
}

}

 

posted on 2019-11-12 14:25  withbear  阅读(342)  评论(0编辑  收藏  举报

导航