(转载)spring配置hibernate 事务。


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事务)

thread

* 如果使用的是全局事务(jta事务)

jta

如果采用的时Hibernate4,使用getCurrentSession()必须配置事务,否则无法取到session

applicationContext.xml配置

 1 <?xml version="1.0" encoding="UTF-8"?>
 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 <?xml version="1.0" encoding="UTF-8"?>
 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数据

Spring整合hibernate4:事务管理,布布扣,bubuko.com

Spring整合hibernate4:事务管理

标签:des   style   blog   http   color   使用