Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1670394
  • 博文数量: 695
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 4027
  • 用 户 组: 普通用户
  • 注册时间: 2013-11-20 21:22
文章分类

全部博文(695)

文章存档

2018年(18)

2017年(74)

2016年(170)

2015年(102)

2014年(276)

2013年(55)

分类: Java

2017-05-18 11:47:43

事务确实是数据库的事情,但是我们得要把事务的起点和终点告诉数据库吧。
如果你直接使用jdbc的话就会需要如下类似的代码

点击(此处)折叠或打开

  1. try{
  2.   conn=DriverManager.getConnection("jdbc:odbc:grade");
  3.   defaultCommit=conn.getAutoCommit();
  4.   conn.setAutoCommit(false);
  5.   stmt=conn.createStatement();
  6.   stmt.executeUpdate(strSQL1);
  7.   stmt.executeUpdate(strSQL2);
  8.   conn.commit();
  9.   }
  10.   catch(Exception e){
  11.   conn.rollback();
  12.   e.printStackTrace();
  13.   }
  14.   finally{
  15.   conn.setAutoCommit(defaultCommit);
  16.   if(stmt!=null){
  17.         stmt.close();
  18.   }
  19.   if(conn!=null){
  20.         stmt.close();
  21.   }
  22.   }

就是将自动提交设为false之后,连续的几个数据库操作,如果成功的话,则提交完成一个事务,如果某个发生异常,则回滚。
而Spring的事务处理,底层也就是这样的,只是spring的方式给程序员提供了便捷,AOP,让程序员不要在关心这些重复的try catch ,只需要关心业务代码。
一般的使用方式是:将Service的方法设置成切点,将dao中的数据库曾、删、改、查操作设置成切面。
将事务的操作方法conn.setAutoCommit(false);conn.commit();conn.rollback();等提取出来做成了一个切面,这样通过配置文件或注解等方式,执行Service切点时会将切面穿进去,实现业务层的事务。

事务都是放在service层的,
使用spring来管理事务的话,可以把事务代码抽取出来,
这样的话,service层的代码简洁了,同时也降低了耦合度。
这一点对大项目来说尤其重要的。 aop确实是强大。

一、      XML,使用tx标签配置拦截器实现事务

Entity类User.java,持久化类,对应数据库表user


点击(此处)折叠或打开

  1. package com.lei.demo.entity;

  2. import javax.persistence.*;

  3. @Entity(name="users")
  4. public class Users {
  5.     
  6.     public Users(){
  7.         super();
  8.     }
  9.     
  10.     @Id
  11.     @GeneratedValue(strategy=GenerationType.AUTO)
  12.     @Column(name="id")
  13.     private Integer id;
  14.     
  15.     @Column(name="user_name",length=32)
  16.     private String user_name;
  17.     
  18.     @Column(name="age")
  19.     private Integer age;
  20.     
  21.     @Column(name="nice_name",length=32)
  22.     private String nice_name;
  23.     
  24.     //属性实现......

  25. }
  26. package com.lei.demo.dao;

  27. import java.util.List;

  28. import javax.annotation.Resource;

  29. import org.hibernate.Query;
  30. import org.hibernate.Session;
  31. import org.hibernate.SessionFactory;
  32. import org.springframework.stereotype.Repository;

  33. import com.lei.demo.entity.Users;

  34. public class UsersDAO {
  35.     private SessionFactory sessionFactory;

  36.     public void setSessionFactory(SessionFactory sessionFactory) {
  37.         this.sessionFactory = sessionFactory;
  38.     }

  39.     public SessionFactory getSessionFactory() {
  40.         return sessionFactory;
  41.     }

  42.     public List<Users> getAllUser(){
  43.         String hsql="from users";
  44.         Session session = sessionFactory.getCurrentSession();
  45.         Query query = session.createQuery(hsql);
  46.         
  47.         return query.list();
  48.     }
  49. }

  50. package com.lei.demo.service;

  51. import javax.annotation.Resource;

  52. import org.springframework.stereotype.Service;
  53. import org.springframework.transaction.annotation.Isolation;
  54. import org.springframework.transaction.annotation.Propagation;
  55. import org.springframework.transaction.annotation.Transactional;

  56. import com.lei.demo.dao.*;

  57. public class UserService {
  58.     private UsersDAO userDao;
  59.     
  60.     public int userCount(){
  61.         return userDao.getAllUser().size();
  62.     }

  63.     public UsersDAO getUserDao() {
  64.         return userDao;
  65.     }

  66.     public void setUserDao(UsersDAO userDao) {
  67.         this.userDao = userDao;
  68.     }

  69. }
xml文件配置

点击(此处)折叠或打开

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns=""
  3.     xmlns:context=""
  4.     xmlns:xsi=""
  5.     xmlns:tx=""
  6.     xmlns:aop=""
  7.     xsi:schemaLocation="
  8.         
  9.         /spring-beans-4.0.xsd
  10.         
  11.         /spring-context-4.0.xsd
  12.         
  13.         /spring-aop-4.0.xsd
  14.         
  15.         /spring-tx-4.0.xsd
  16.         ">

  17.     <!-- Hibernate4 -->
  18.     <!-- 加载资源文件 其中包含变量信息,必须在Spring配置文件的最前面加载,即第一个加载-->
  19.     <context:property-placeholder location="classpath:persistence-mysql.properties" />
  20.     
  21.     <bean id="sessionFactory"
  22.         class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
  23.         <property name="dataSource" ref="dataSource" />
  24.         <property name="packagesToScan">
  25.             <list>
  26.                 <!-- 可以加多个包 -->
  27.                 <value>com.lei.demo.entity</value>
  28.             </list>
  29.         </property>
  30.         <property name="hibernateProperties">
  31.             <props>
  32.                 <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
  33.                 <prop key="hibernate.dialect">${hibernate.dialect}</prop>
  34.                 <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
  35.                 <!-- <prop key="hibernate.current_session_context_class">thread</prop> -->
  36.             </props>
  37.         </property>
  38.     </bean>
  39.     
  40.     <!-- 数据库映射 -->
  41.     <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  42.       <property name="driverClassName" value="${jdbc.driverClassName}" />
  43.       <property name="url" value="${jdbc.url}" />
  44.       <property name="username" value="${jdbc.user}" />
  45.       <property name="password" value="${jdbc.pass}" />
  46.    </bean>
  47.    
  48.     <!-- 配置Hibernate事务管理器 -->
  49.     <bean id="transactionManager"
  50.         class="org.springframework.orm.hibernate4.HibernateTransactionManager">
  51.       <property name="sessionFactory" ref="sessionFactory" />
  52.    </bean>
  53.    
  54.    <!-- 配置事务异常封装 -->
  55.    <bean id="persistenceExceptionTranslationPostProcessor"
  56.        class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
  57.    
  58.    <!-- 声明式容器事务管理 ,transaction-manager指定事务管理器为transactionManager -->
  59.     <tx:advice id="txAdvice" transaction-manager="transactionManager">
  60.         <tx:attributes>
  61.             <tx:method name="add*" propagation="REQUIRED" />
  62.             <tx:method name="get*" propagation="REQUIRED" />
  63.             <tx:method name="*" read-only="true" />
  64.         </tx:attributes>
  65.     </tx:advice>
  66.     
  67.     <aop:config expose-proxy="true">
  68.         <!-- 只对业务逻辑层实施事务 -->
  69.         <aop:pointcut id="txPointcut" expression="execution(* com.lei.demo.service..*.*(..))" />
  70.         <!-- Advisor定义,切入点和通知分别为txPointcut、txAdvice -->
  71.         <aop:advisor pointcut-ref="txPointcut" advice-ref="txAdvice"/>
  72.     </aop:config>
  73.     
  74. </beans>

其中主要配置中是tx:adviceaop:config两个配置节,以Spring AOP的方式实现事务管理。

tx:advice配置了事务的管理者是transactionManager,同时tx:method也规定了如果方法名匹配“add*”和“get*”方法时使用事务,propagation是设定事务的传播级别。除了“add*”和“get*”方法,其他的方法的事务是只读的(典型地,对于只执行查询的事务你会将该属性设为true,如果出现了更新、插入或是删除语句时只读事务就会失败)

aop:config指定了一个aop:pointcut去引用上边的advice。

这样就通过AOP的拦截机制实现了事务,当然你还要用Spring的方式自己配置UserDAO和UserService。
joinpoint:切入点
pointcut :切入点集合
aspect:切面
advice:切面上的建议,例如before或after(每个切点方法对应一个advice,一个切面上可有多个advice)
target:被代理对象
weave:织入

参考:
http://www.cnblogs.com/leiOOlei/p/3725911.html

阅读(679) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~