博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring整合hibernate4:事务管理
阅读量:4311 次
发布时间:2019-06-06

本文共 5622 字,大约阅读时间需要 18 分钟。

转自:

 

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 
2
17 18
19
20
21 22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 40
41
42 43
44
45
org.hibernate.dialect.MySQLDialect
46
true
47
thread
48
49
50 51
52
53
po
54
55
56
57 58 59
60
61
62
63 64
65
66
67
68
69
70 71
72
73
74
75
76 77

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 
2
17 18
19
20
21 22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 40
41
42 43
44
45
org.hibernate.dialect.MySQLDialect
46
true
47
thread
48
49
50 51
52
53
po
54
55
56
57 58 59
60
61
62
63 64

 

事物注解方式: @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数据

转载于:https://www.cnblogs.com/laobiao/p/5627959.html

你可能感兴趣的文章
MQTT协议笔记之mqtt.io项目HTTP协议支持
查看>>
(转)jQuery中append(),prepend()与after(),before()的区别
查看>>
Tecplot: Legend和图像中 Dashed/Dash dot/Long dash 等虚线显示没有区别的问题
查看>>
win8 开发之旅(2) --连连看游戏开发 项目错误的总结
查看>>
视频转换工具ffmpeg
查看>>
一、 object c -基础学习第一天 如何定义一个类
查看>>
C#调用C++编译的DLL详解
查看>>
Kali Linux的安装
查看>>
我的大学生活-5-08-赵心宁
查看>>
SQLServer视图
查看>>
入门阶段
查看>>
Android中使用http协议访问网络
查看>>
vs win32 & MFC 指针默认位置
查看>>
Join 与 CountDownLatch 之间的区别
查看>>
js存cookie
查看>>
vc6下dll调试
查看>>
Ubuntu apt常用命令
查看>>
struts2 配置(部分)
查看>>
python代码迷之错误(ModuleNotFoundError: No module named 'caffe.proto')
查看>>
nodejs adm-zip 解压文件 中文文件名乱码 问题解决
查看>>