Spring整合hibernate4:事务管理
Spring整合hibernate4:事务管理
Spring和Hibernate整合后,通过Hibernate API进行数据库操作时发现每次都要opensession,close,beginTransaction,commit,这些都是重复的工作,我们可以把事务管理部分交给spring框架完成。
配置事务(xml方式)
使用spring管理事务后在dao中不再需要调用beginTransaction和commit,也不需要调用session.close(),使用API sessionFactory.getCurrentSession()来替代sessionFactory.openSession()
1 @Repository
2 public class UserDaoImpl implements UserDao {
3 @Autowired
4 private SessionFactory sessionFactory;
5
6 public User findUserById(int id) {
7 Session session = sessionFactory.getCurrentSession();
8 User user = (User)session.get(User.class, id);
9 session.delete(user);
10
11 return user;
12 }
13 }
采用getCurrentSession()创建的session会绑定到当前线程中,而采用openSession()创建的session则不会。
采用getCurrentSession()创建的session在commit或rollback时会自动关闭,而采用openSession()创建的session必须手动关闭。
使用getCurrentSession()需要在hibernate.cfg.xml文件中加入如下配置:
* 如果使用的是本地事务(jdbc事务)
<property name="hibernate.current_session_context_class">thread</property>
* 如果使用的是全局事务(jta事务)
<property name="hibernate.current_session_context_class">jta</property>
如果采用的时Hibernate4,使用getCurrentSession()必须配置事务,否则无法取到session
applicationContext.xml配置
1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans
3 xmlns="http://www.springframework.org/schema/beans"
4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5 xmlns:p="http://www.springframework.org/schema/p"
6 xmlns:context="http://www.springframework.org/schema/context"
7 xmlns:aop="http://www.springframework.org/schema/aop"
8 xmlns:tx="http://www.springframework.org/schema/tx"
9 xmlns:jpa="http://www.springframework.org/schema/data/jpa"
10 xmlns:cache="http://www.springframework.org/schema/cache"
11 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
12 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
13 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
14 http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
15 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
16 http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
17
18 <context:component-scan base-package="dao"/>
19 <context:component-scan base-package="service"/>
20 <context:component-scan base-package="test"/>
21
22 <context:property-placeholder location="classpath:dbcp.properties"/>
23 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
24 <property name="driverClassName" value="${driverClassName}" />
25 <property name="url" value="${url}" />
26 <property name="username" value="${mysqlusername}" />
27 <property name="password" value="${mysqlpassword}" />
28 <property name="maxActive" value="${maxActive}" />
29 <property name="maxIdle" value="${maxIdle}" />
30 <property name="minIdle" value="${minIdle}" />
31 <property name="maxWait" value="${maxWait}" />
32 <property name="initialSize" value="${initialSize}" />
33 <property name="logAbandoned" value="${logAbandoned}" />
34 <property name="removeAbandoned" value="${removeAbandoned}" />
35 <property name="removeAbandonedTimeout" value="${removeAbandonedTimeout}" />
36 <property name="timeBetweenEvictionRunsMillis" value="${timeBetweenEvictionRunsMillis}" />
37 <property name="numTestsPerEvictionRun" value="${numTestsPerEvictionRun}" />
38 </bean>
39
40 <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
41 <property name="dataSource" ref="dataSource" />
42
43 <property name="hibernateProperties">
44 <props>
45 <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
46 <prop key="hibernate.show_sql">true</prop>
47 <prop key="current_session_context_class">thread</prop>
48 </props>
49 </property>
50
51 <property name="packagesToScan">
52 <list>
53 <value>po</value>
54 </list>
55 </property>
56 </bean>
57
58
59 <!--hibernate4必须配置为开启事务 否则 getCurrentSession()获取不到-->
60 <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
61 <property name="sessionFactory" ref="sessionFactory"></property>
62 </bean>
63
64 <tx:advice id="txAdvice" transaction-manager="txManager">
65 <tx:attributes>
66 <tx:method name="find*" propagation="REQUIRED" />
67 <tx:method name="*" read-only="true"/>
68 </tx:attributes>
69 </tx:advice>
70
71 <aop:config proxy-target-class="true">
72 <!-- <aop:advisor advice-ref="txAdvice" pointcut="execution(* dao.*.*(..))"/> -->
73 <aop:pointcut expression="execution(* dao.*.*(..))" id="pointcut"/>
74 <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
75 </aop:config>
76
77 </beans>
Spring中Propagation类的事务属性详解:
PROPAGATION_REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED:支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务。
配置事务(声明方式)
需要在xml配制中设置<tx:annotation-driven transaction-manager="transactionManager">
1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans
3 xmlns="http://www.springframework.org/schema/beans"
4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5 xmlns:p="http://www.springframework.org/schema/p"
6 xmlns:context="http://www.springframework.org/schema/context"
7 xmlns:aop="http://www.springframework.org/schema/aop"
8 xmlns:tx="http://www.springframework.org/schema/tx"
9 xmlns:jpa="http://www.springframework.org/schema/data/jpa"
10 xmlns:cache="http://www.springframework.org/schema/cache"
11 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
12 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
13 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
14 http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
15 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
16 http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
17
18 <context:component-scan base-package="dao"/>
19 <context:component-scan base-package="service"/>
20 <context:component-scan base-package="test"/>
21
22 <context:property-placeholder location="classpath:dbcp.properties"/>
23 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
24 <property name="driverClassName" value="${driverClassName}" />
25 <property name="url" value="${url}" />
26 <property name="username" value="${mysqlusername}" />
27 <property name="password" value="${mysqlpassword}" />
28 <property name="maxActive" value="${maxActive}" />
29 <property name="maxIdle" value="${maxIdle}" />
30 <property name="minIdle" value="${minIdle}" />
31 <property name="maxWait" value="${maxWait}" />
32 <property name="initialSize" value="${initialSize}" />
33 <property name="logAbandoned" value="${logAbandoned}" />
34 <property name="removeAbandoned" value="${removeAbandoned}" />
35 <property name="removeAbandonedTimeout" value="${removeAbandonedTimeout}" />
36 <property name="timeBetweenEvictionRunsMillis" value="${timeBetweenEvictionRunsMillis}" />
37 <property name="numTestsPerEvictionRun" value="${numTestsPerEvictionRun}" />
38 </bean>
39
40 <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
41 <property name="dataSource" ref="dataSource" />
42
43 <property name="hibernateProperties">
44 <props>
45 <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
46 <prop key="hibernate.show_sql">true</prop>
47 <prop key="current_session_context_class">thread</prop>
48 </props>
49 </property>
50
51 <property name="packagesToScan">
52 <list>
53 <value>po</value>
54 </list>
55 </property>
56 </bean>
57
58
59 <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
60 <property name="sessionFactory" ref="sessionFactory"></property>
61 </bean>
62 <tx:annotation-driven transaction-manager="txManager"/>
63
64 </beans>
事物注解方式: @Transactional
当标于类前时,标示类中所有方法都进行事物处理,以下代码在service层进行事务处理(给Service层配置事务是比较好的方式,因为一个 Service层方法操作可以关联到多个DAO的操作。在Service层执行这些Dao操作,多DAO操作有失败全部回滚,成功则全部提交。)
1 @Service
2 @Transactional
3 public class UserServiceImpl implements UserService {
4 @Autowired
5 private UserDao userDao;
6
7 public User getUserById(int id) {
8 return userDao.findUserById(id);
9 }
10 }
当类中某些方法不需要事物时:
1 @Service
2 @Transactional
3 public class UserServiceImpl implements UserService {
4 @Autowired
5 private UserDao userDao;
6
7 @Transactional(propagation = Propagation.NOT_SUPPORTED)
8 public User getUserById(int id) {
9 return userDao.findUserById(id);
10 }
11 }
@Transactional(propagation=Propagation.REQUIRED)
如果有事务, 那么加入事务, 没有的话新建一个(默认情况下)
@Transactional(propagation=Propagation.NOT_SUPPORTED)
容器不为这个方法开启事务
@Transactional(propagation=Propagation.REQUIRES_NEW)
不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务
@Transactional(propagation=Propagation.MANDATORY)
必须在一个已有的事务中执行,否则抛出异常
@Transactional(propagation=Propagation.NEVER)
必须在一个没有的事务中执行,否则抛出异常(与Propagation.MANDATORY相反)
@Transactional(propagation=Propagation.SUPPORTS)
如果其他bean调用这个方法,在其他bean中声明事务,那就用事务.如果其他bean没有声明事务,那就不用事务.
事物超时设置:
@Transactional(timeout=30) //默认是30秒
事务隔离级别:
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
读取未提交数据(会出现脏读, 不可重复读) 基本不使用
@Transactional(isolation = Isolation.READ_COMMITTED)
读取已提交数据(会出现不可重复读和幻读)
@Transactional(isolation = Isolation.REPEATABLE_READ)
可重复读(会出现幻读)
@Transactional(isolation = Isolation.SERIALIZABLE)
串行化
MYSQL: 默认为REPEATABLE_READ级别
SQLSERVER: 默认为READ_COMMITTED
脏读 : 一个事务读取到另一事务未提交的更新数据
不可重复读 : 在同一事务中, 多次读取同一数据返回的结果有所不同, 换句话说,
后续读取可以读到另一事务已提交的更新数据. 相反, "可重复读"在同一事务中多次
读取数据时, 能够保证所读数据一样, 也就是后续读取不能读到另一事务已提交的更新数据
幻读 : 一个事务读到另一个事务已提交的insert数据
Spring整合hibernate4:事务管理的更多相关文章
- Spring整合JMS——事务管理
Spring提供了一个JmsTransactionManager用于对JMS ConnectionFactory做事务管理.这将允许JMS应用利用Spring的事务管理特性.JmsTransactio ...
- Spring对Hibernate事务管理
谈Spring事务管理之前我们想一下在我们不用Spring的时候,在Hibernate中我们是怎么进行数据操作的.在Hibernate中 我们每次进行一个操作的的时候我们都是要先开启事务,然后进行数据 ...
- Spring对Hibernate事务管理【转】
在谈Spring事务管理之前我们想一下在我们不用Spring的时候,在Hibernate中我们是怎么进行数据操作的.在Hibernate中我们每次进行一个操作的的时候我们都是要先开启事务,然后进行数据 ...
- spring声明式事务管理方式( 基于tx和aop名字空间的xml配置+@Transactional注解)
1. 声明式事务管理分类 声明式事务管理也有两种常用的方式, 一种是基于tx和aop名字空间的xml配置文件,另一种就是基于@Transactional注解. 显然基于注解的方式更简单易用,更清爽. ...
- Spring框架的事务管理之编程式的事务管理(了解)
1. 说明:Spring为了简化事务管理的代码:提供了模板类 TransactionTemplate,所以手动编程的方式来管理事务,只需要使用该模板类即可!!2.手动编程方式的具体步骤如下: 1.步骤 ...
- Spring入门5.事务管理机制
Spring入门5.事务管理机制 20131126 代码下载 : 链接: http://pan.baidu.com/s/1kYc6c 密码: 233t 回顾之前的知识,Spring 最为核心的两个部分 ...
- spring 声明式事务管理
简单理解事务: 比如你去ATM机取5000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉5000元钱:然后ATM出5000元钱.这两个步骤必须是要么都执行要么都不执行.如果银行卡扣除了5000块但 ...
- Spring声明式事务管理基于@Transactional注解
概述:我们已知道Spring声明式事务管理有两种常用的方式,一种是基于tx/aop命名空间的xml配置文件,另一种则是基于@Transactional 注解. 第一种方式我已在上文为大 ...
- Spring声明式事务管理基于tx/aop命名空间
目的:通过Spring AOP 实现Spring声明式事务管理; Spring支持编程式事务管理和声明式事务管理两种方式. 而声明式事务管理也有两种常用的方式,一种是基于tx/aop命名空间的xml配 ...
随机推荐
- python__标准库 : 测试代码运行时间(timeit)
用 timeit.Timer.timeit() 方法来测试代码的运行时间: from timeit import Timer def t1(): li = [] ): li.append(i) def ...
- CSS选取指定位置标签first-child、last-child、nth-child
1.first-child 选择列表中的第一个标签. 2.last-child 选择列表中的最后一个标签 3.nth-child(n) 选择列表中的第n个标签 4.nth-child(2n) 选择列表 ...
- [Luogu1341]无序字母对(欧拉回路)
按题意给定字符串建无向图,找欧拉回路 按照定义,当没有奇数度点或者只有2个奇数度点时才有欧拉回路 Code #include <cstdio> #include <algorithm ...
- urllib使用一
urllib.urlopen()方法: 参数: 1.url(要访问的网页链接http:或者是本地文件file:) 2.data(如果有,就会由GET方法变为POST方法,提交的数据格式必须是appli ...
- Android 拍照或相册选择照片进行显示缩放位图 Demo
拍照后直接使用 BitmapFactory.decodeStream(...) 进行创建 Bitmap 并显示是有问题的. Bitmap 是个简单对象,它只存储实际像素数据,也就是说,即使原始照片已压 ...
- 9,Linux下的python3,virtualenv,Mysql、nginx、redis安装配置
常用服务安装部署 学了前面的Linux基础,想必童鞋们是不是更感兴趣了?接下来就学习常用服务部署吧! 安装环境: centos7 + vmware + xshell MYSQL(mariadb) ...
- P1862 输油管道问题
P1862 输油管道问题 题目背景 听说最近石油危机 所以想到了这题 题目描述 某石油公司计划建造一条由东向西的主要输油管道.该管道要穿过一个有n口油井的油田.从每口油井都要有一条输油管道沿最短路径( ...
- Python 两种方式实现斐波那契数列
斐波那契数列指的是这样一个数列 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946 ...
- 孤荷凌寒自学python第十八天python变量的作用范围
孤荷凌寒自学python第十八天python函数的形参与变量的范围 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 一.在python的函数中各种不同的形式参数在定义的先后顺序上有规定: 必须 ...
- Linux再谈互斥锁与条件变量
原文地址:http://blog.chinaunix.net/uid-27164517-id-3282242.html pthread_cond_wait总和一个互斥锁结合使用.在调用pthread_ ...