spring事务管理例子

为了对spring开启事务有进一步的了解,下面看这个简单的例子:
1 实体类User.java

  1. package org.lab24.entity; 
  2.  
  3. import java.io.Serializable; 
  4.  
  5. import javax.persistence.Entity; 
  6. import javax.persistence.GeneratedValue; 
  7. import javax.persistence.GenerationType; 
  8. import javax.persistence.Id; 
  9. import javax.persistence.Table; 
  10.  
  11. @Entity 
  12. @Table(name = "User"
  13. public class User implements Serializable{ 
  14.  
  15.     public User(){ 
  16.     } 
  17.  
  18.      @Id   
  19.      @GeneratedValue(strategy = GenerationType.AUTO) 
  20.     private Integer id; 
  21.     private String name; 
  22.      
  23.     public Integer getId() { 
  24.         return id; 
  25.     } 
  26.     public void setId(Integer id) { 
  27.         this.id = id; 
  28.     } 
  29.     public String getName() { 
  30.         return name; 
  31.     } 
  32.     public void setName(String name) { 
  33.         this.name = name; 
  34.     } 

2 抽象dao类,这里设为抽象类主要是为了不让它直接实例化对象(这里这样设计好像有点多余,这个应该是一种设计模式吧):

  1. package org.lab24.dao; 
  2.  
  3. import java.util.List; 
  4.  
  5. import org.springframework.orm.hibernate3.support.HibernateDaoSupport; 
  6.  
  7. public abstract class BasicDao extends HibernateDaoSupport{ 
  8.      
  9.     //这里的返回值,可以直接返回getHibernateTemplate().save(entity)的值,这个会返回新插入记录的键值,也可以如下方式,返回一个持久化到数据库的对象 
  10.     public Object save(Object entity) throws Exception{ 
  11.         getHibernateTemplate().save(entity); 
  12.         return entity; 
  13.     } 
  14.      
  15.     public List getAllObjects(Class object)throws Exception{ 
  16.         return getHibernateTemplate().find("from " + object.getName()); 
  17.     } 
  18.      
  19.     //delete返回的是一个空值,因为记录都删除了,就不会有键值或对象的返回 
  20.     public void delete(Object entity)throws Exception{ 
  21.         getHibernateTemplate().delete(entity); 
  22.     } 

3 dao实现类:

  1. package org.lab24.dao.impl; 
  2.  
  3. import java.util.List; 
  4.  
  5. import org.lab24.dao.BasicDao; 
  6. import org.springframework.stereotype.Repository; 
  7. import org.springframework.stereotype.Service; 
  8. import org.springframework.transaction.annotation.Propagation; 
  9. import org.springframework.transaction.annotation.Transactional; 
  10.  
  11.  
  12. /*
  13. * @Service用于标注业务层组件,
  14. * @Controller用于标注控制层组件(如struts中的action),
  15. * @Repository用于标注数据访问组件,即DAO组件,
  16. * 而@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。   
  17. */ 
  18. @Repository("basicDaoService"
  19. /*
  20. * readOnly表示事务是否只读的,不能进行插入更新操作
  21. * propagation = Propagation.REQUIRED表示执行这个类实例方法需开启事务
  22. * rollbackFor = Throwable.class表示遇到Throwable类及子类(即发生了异常)时事务进行回滚操作
  23. */ 
  24. @Transactional(readOnly=false , propagation = Propagation.REQUIRED , rollbackFor = Throwable.class
  25. public class BasicDaoImpl extends BasicDao{ 
  26.  
  27.     @Override 
  28.     public Object save(Object entity) throws Exception { 
  29.         return super.save(entity); 
  30.     } 
  31.  
  32.     @Override 
  33.     public void delete(Object entity) throws Exception { 
  34.         super.delete(entity); 
  35.     } 
  36.  
  37.     @Override 
  38.     public List getAllObjects(Class object) throws Exception { 
  39.         List objectList =  super.getAllObjects(object); 
  40.         return objectList; 
  41.     } 
  42.      
  43.      

4 业务层接口类:

  1. package org.lab24.service; 
  2.  
  3. import java.util.List; 
  4.  
  5. import org.lab24.entity.User; 
  6.  
  7.  
  8. public interface UserService { 
  9.  
  10.     public void save(User user)throws Exception; 
  11.      
  12.     public List getAllUsers()throws Exception; 
  13.      
  14.     public void deleteUser(User user)throws Exception; 
  15.      

5 业务层实现类:

  1. package org.lab24.serviceImpl; 
  2.  
  3. import java.util.List; 
  4.  
  5. import javax.annotation.Resource; 
  6.  
  7. import org.lab24.dao.impl.BasicDaoImpl; 
  8. import org.lab24.entity.User; 
  9. import org.lab24.service.UserService; 
  10. import org.springframework.stereotype.Service; 
  11.  
  12. @Service("userService")//自己给这个交给spring管理的bean一个名字,若不给,就直接用类的名字第一个字母改为小写而形成bean的名字 
  13. public class UserServiceImpl implements UserService{ 
  14.  
  15.     @Resource 
  16.     BasicDaoImpl basicDaoService;//basicDaoService对应BasicDaoImpl成为数据访问组件的bean名字 
  17.      
  18.     public List getAllUsers() throws Exception{ 
  19.         List userList = basicDaoService.getAllObjects(User.class); 
  20.         return userList; 
  21.     } 
  22.  
  23.     public void save(User user) throws Exception{ 
  24.         basicDaoService.save(user); 
  25.     } 
  26.  
  27.     public void deleteUser(User user) throws Exception { 
  28.         basicDaoService.delete(user); 
  29.     } 
  30.  
  31.      

6 测试类:

  1. package org.lab24.junit.test; 
  2.  
  3. import java.util.Iterator; 
  4. import java.util.List; 
  5.  
  6. import javax.annotation.Resource; 
  7.  
  8. import org.junit.BeforeClass; 
  9. import org.junit.Test; 
  10. import org.junit.runner.RunWith; 
  11. import org.lab24.entity.User; 
  12. import org.lab24.service.UserService; 
  13. import org.springframework.test.context.ContextConfiguration; 
  14. import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests; 
  15. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 
  16.  
  17.  
  18. @ContextConfiguration(locations = "classpath:applicationContext.xml")  
  19. @RunWith(SpringJUnit4ClassRunner.class)   
  20.  
  21. public class UserServiceImplTest{ 
  22.      
  23.     @Resource 
  24.     private UserService userService;//userService对应UserServiceImpl成为服务组件的bean名字 
  25.      
  26.     @BeforeClass 
  27.     public static void setUpBeforeClass() throws Exception { 
  28.     } 
  29.  
  30.     @Test 
  31.     public void testGetAllUsers() { 
  32.         List<User> users = null
  33.         try
  34.             users = userService.getAllUsers(); 
  35.         } catch (Exception e) { 
  36.             e.printStackTrace(); 
  37.         } 
  38.         Iterator iterator = users.iterator(); 
  39.         User temp; 
  40.         while(iterator.hasNext()){ 
  41.             temp = (User) iterator.next(); 
  42.             System.out.println("ID:" + temp.getId() + "   name:" + temp.getName()); 
  43.         } 
  44.     } 
  45.  
  46.     @Test 
  47.     public void testSave() { 
  48.         User user = new User(); 
  49.          
  50.         user.setName("333333333"); 
  51.         try
  52.             userService.save(user); 
  53.         } catch (Exception e) { 
  54.             e.printStackTrace(); 
  55.         } 
  56.     } 
  57.  

7 spring配置文件:

  1. <?xml version="1.0" encoding="UTF-8"?> 
  2. <beans xmlns="http://www.springframework.org/schema/beans" 
  3.     xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr" 
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  5.     xmlns:context="http://www.springframework.org/schema/context" 
  6.     xmlns:tx="http://www.springframework.org/schema/tx"  
  7.     xmlns:ehcache="http://www.springmodules.org/schema/ehcache" 
  8.     xsi:schemaLocation="http://www.springframework.org/schema/beans 
  9.     http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
  10.     http://www.springframework.org/schema/context 
  11.     http://www.springframework.org/schema/context/spring-context-2.5.xsd 
  12.     http://www.springframework.org/schema/tx 
  13.     http://www.springframework.org/schema/tx/spring-tx-2.5.xsd 
  14.     http://www.springmodules.org/schema/ehcache 
  15.     http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd 
  16.     http://www.directwebremoting.org/schema/spring-dwr 
  17.     http://www.directwebremoting.org/schema/spring-dwr-3.0.xsd" 
  18.     default-autowire="byName" default-lazy-init="true"> 
  19.  
  20.     <context:component-scan base-package="org.lab24.dao.impl" /> 
  21.     <context:component-scan base-package="org.lab24.serviceImpl" /> 
  22.      
  23.     <bean id="lobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" 
  24.         lazy-init="true" /> 
  25.      
  26.     <!--  缓存管理  --> 
  27.     <bean id="cacheManager" 
  28.         class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> 
  29.         <property name="configLocation"> 
  30.             <value>classpath:ehcache.xml</value> 
  31.         </property> 
  32.  
  33.     </bean> 
  34.      
  35.        
  36.     <bean id="sessionFactory" 
  37.         class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" > 
  38.         <property name="lobHandler" ref="lobHandler" /> 
  39.         <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" /> 
  40.         <property name="configLocation"> 
  41.             <value>classpath:hibernate.cfg.xml</value> 
  42.         </property> 
  43.     </bean> 
  44.     <bean id="transactionManager" 
  45.         class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
  46.         <property name="sessionFactory" ref="sessionFactory" /> 
  47.     </bean> 
  48.      
  49.     <tx:annotation-driven transaction-manager="transactionManager" 
  50.         proxy-target-class="true" /> 
  51.      
  52.      
  53.     <!-- 在此进行自动代理配置 --> 
  54.     <bean id="beanNameAutoProxyCreator" 
  55.         class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> 
  56.         <property name="proxyTargetClass" value="true" /> 
  57.         <property name="beanNames"> 
  58.             <list> 
  59.                 <value>*Impl</value> 
  60.             </list> 
  61.         </property> 
  62.     </bean> 
  63.  
  64.      
  65. </beans> 

8 hibernate配置文件:

  1. <?xml version="1.0" encoding="utf-8" ?> 
  2. <!DOCTYPE hibernate-configuration 
  3. PUBLIC "-//Hibernate/Hibernate Configuration DTD/EN" 
  4. "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 
  5.  
  6. <hibernate-configuration> 
  7.  
  8.     <session-factory> 
  9.          
  10.     <property name="hibernate.connection.driver_class" >com.mysql.jdbc.Driver</property> 
  11.         <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> 
  12.         <property name="hibernate.connection.username">root</property> 
  13.         <property name="hibernate.connection.password"></property> 
  14.         <property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/wtb</property> 
  15.  
  16.  
  17.         <!-- Connection Parameters --> 
  18.         <property name="hibernate.connection.provider_class"> 
  19.             org.hibernate.connection.C3P0ConnectionProvider 
  20.         </property> 
  21.  
  22.         <!-- Connection Pool --> 
  23.         <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 --> 
  24.         <property name="hibernate.c3p0.acquireIncrement">3</property> 
  25.  
  26.         <!--两次连接中间隔时间,单位毫秒。Default: 1000 --> 
  27.         <property name="hibernate.c3p0.acquireRetryDelay">1000</property> 
  28.         <!--连接关闭时默认将所有未提交的操作回滚。Default: false --> 
  29.         <property name="hibernate.c3p0.autoCommitOnClose">false</property> 
  30.         <!--连接池中保留的最大连接数。Default: 15 --> 
  31.         <property name="hibernate.c3p0.maxPoolSize">15</property> 
  32.         <property name="hibernate.c3p0.max_size">20</property> 
  33.         <property name="hibernate.c3p0.min_size">5</property> 
  34.         <property name="hibernate.c3p0.timeout">5000</property> 
  35.  
  36.         <property name="hibernate.c3p0.acquire_increment">5</property> 
  37.         <property name="hibernate.c3p0.idle_test_period">3000</property> 
  38.         <property name="hibernate.c3p0.preferredTestQuery"> 
  39.             select id from test where id=1 
  40.         </property> 
  41.         <property name="hibernate.c3p0.testConnectionOnCheckin"> 
  42.             true 
  43.         </property> 
  44.          
  45.          
  46.         <!-- 启动时删数据库中的表,然后创建,退出时不删除数据表,如果没有下面的属性的话,那么要手动写sql语句来建表,才能进行数据库的操作--> 
  47.         <property name="hbm2ddl.auto">update</property> 
  48.          
  49.         <!--
  50.             为单向关联(一对一, 多对一)的外连接抓取(outer join fetch)树设置最大深度. 值为0意味着将关闭默认的外连接抓取.
  51.         --> 
  52.         <property name="hibernate.max_fetch_depth">3</property> 
  53.         <property name="hibernate.order_updates">true</property> 
  54.         <property name="hibernate.jdbc.fetch_size">100</property> 
  55.         <property name="hibernate.jdbc.batch_size">0</property> 
  56.         <property name="hibernate.show_sql">false</property> 
  57.         <property name="hibernate.format_sql">true</property> 
  58.  
  59.         <property name="hibernate.ejb.naming_strategy"> 
  60.             DefaultComponentSafeNamingStrategy 
  61.     </property> 
  62.         <property name="hibernate.query.substitutions"> 
  63.             true=1, false=0 
  64.     </property> 
  65.         <property name="hibernate.query.factory_class"> 
  66.             org.hibernate.hql.ast.ASTQueryTranslatorFactory 
  67.     </property> 
  68.         <!-- 
  69.             2.0 <property 
  70.             name="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</property> 
  71.         --> 
  72.         <property name="hibernate.cglib.use_reflection_optimizer"> 
  73.             false 
  74.     </property> 
  75.         <property name="hiberante.defaultAutoCommit">false</property> 
  76.  
  77.         <property name="hibernate.cache.provider_class"> 
  78.             org.hibernate.cache.EhCacheProvider 
  79.     </property> 
  80.         <property name="cache.use_second_level_cache">true</property> 
  81.  
  82.         <!-- Transaction Configuration --> 
  83.         <property name="hibernate.transaction.factory_class"> 
  84.             org.hibernate.transaction.JDBCTransactionFactory 
  85.     </property> 
  86.  
  87.     <mapping class="org.lab24.entity.User" /> 
  88.  
  89.  
  90.     </session-factory> 
  91.  
  92. </hibernate-configuration> 

我们可以从dao的实现类里面看到它上面有@transactional标签,它要求执行它的实例化方法时开启事务(propagation

= Propagation.REQUIRED),因为数据库的操作是要以事务的形式来保证数据的一致性的,所以要开启事务,如果有需

要,我们也可以在业务层开启事务,如这里在dao的实现类里开启事务,那么spring在用户调用BasicDaoImpl类的实例对

象方法时就会开启事务,当这个方法结束后,事务注提交,这时数据库才有新的记录(如用插入或更新操作),当我们在

UserServiceImpl类里也配置要求开启事务,那么只有在UserServiceImpl方法结束后,事务才提交,数据库的信息才得

以更新,而不是在BasicDaoImpl类方法调用完了就提交,不过这也是取决以事务配置方式,即propagation设置,可参照

前面博客讲到的事务设置的知识。


补充事务基本知识:

数据库事务概念
什么是数据库事务?

事务(transaction)是由一系列操作序列构成的程序执行单元,这些操作要么都做,要么都不做,是一个不可分割的工

作单位。

数据库事务的四个基本性质(ACID)
1. 原子性(Atomicity)
事务的原子性是指事务中包含的所有操作要么全做,要么全不做(all or none)。

2. 一致性(Consistency)
在事务开始以前,数据库处于一致性的状态,事务结束后,数据库也必须处于一致性状态。

拿银行转账来说,一致性要求事务的执行不应改变A、B 两个账户的金额总和。如果没有这种一致性要求,转账过程中就

会发生钱无中生有,或者不翼而飞的现象。事务应该把数据库从一个一致性状态转换到另外一个一致性状态。

3. 隔离性(Isolation)
事务隔离性要求系统必须保证事务不受其他并发执行的事务的影响,也即要达到这样一种效果:对于任何一对事务T1 和

T2,在事务 T1 看来,T2 要么在 T1 开始之前已经结束,要么在 T1 完成之后才开始执行。这样,每个事务都感觉不到

系统中有其他事务在并发地执行。

4. 持久性(Durability)
一个事务一旦成功完成,它对数据库的改变必须是永久的,即便是在系统遇到故障的情况下也不会丢失。数据的重要性

决定了事务持久性的重要性。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值