今天做个规划整理,发现需要用到hibernate事务,特意研究了下;
一、hibernate是什么?
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用。
使用hibernate,最常用的场景是,使用它的ORM机制,然后把传统的关系型数据库操作,转换为面向对象的方式来操作。
比如: 通过操作java类对象,直接存储到数据库中;
二、什么是sessionfactory
SessionFactory接口负责初始化Hibernate。它充当数据存储源的代理,并负责创建Session对象。这里用到了工厂模式。需要注意的是SessionFactory并不是轻量级的,因为一般情况下,一个项目通常只需要一个SessionFactory就够,当需要操作多个数据库时,可以为每个数据库指定一个SessionFactory。
<!-- hibernate sessionFactory配置 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 扫描加载映射实体类对象 -->
<property name="packagesToScan" value="com.*.*.*.beans.po" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.autoReconnect">true</prop>
<prop key="javax.persistence.validation.mode">none</prop>
<!-- <prop key="hibernate.connection.autocommit">false</prop> -->
<!--<prop key="hibernate.current_session_context_class">thread</prop>
--></props>
</property>
</bean>
三、什么是Session
hibernateSession是用来表示,应用程序和数据库的一次交互(会话)。在这个Session中,包含了一般的持久化方法(CRUD);
Session的主要功能是提供对映射的实体类实例的创建,读取和删除操作。
@Repository
public class BaseDao extends HibernateDaoSupport {
/**
* <p class="detail">
* 功能:返回当前请求所绑定的数据库session
* </p>
* @return
*/
public Session getCurrenSession(){
return this.getHibernateTemplate().getSessionFactory().getCurrentSession();
}
}
友情提醒:
Session是一个轻量级对象(线程不安全),通常将每个Session实例和一个数据库事务绑定,也就是每执行一个数据库事务,都应该先创建一个新的Session实例; 多表更新数据操作时,请务必保证是一个sesison实例,以便数据更新一致,同时也可保证回滚也一致;
四、什么是transactionManager;
事务管理对于企业应用来说是至关重要的,即使出现异常情况,它也可以保证数据的一致性。
spring支持编程式事务管理和声明式事务管理两种方式。
基于编程式事务管理配置
xml配置
<!-- 事务管理器(在service层面上实现事务管理) -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 事物模板 -->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager" />
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
示例代码(百度找的)
public class BankServiceImpl implements BankService {
private BankDao bankDao;
private TransactionTemplate transactionTemplate;
......
public boolean transfer(final Long fromId, final Long toId, final double amount) {
//调用一个回调函数
return (Boolean) transactionTemplate.execute(new TransactionCallback(){
public Object doInTransaction(TransactionStatus status) {
Object result;
try {
result = bankDao.transfer(fromId, toId, amount);
} catch (Exception e) {
status.setRollbackOnly();
result = false;
System.out.println("Transfer Error!");
}
return result;
}
});
}
}
基于注解的声明式事务管理配置
<!-- 注解事务支持 -->
<!-- enable transaction annotation support -->
<tx:annotation-driven transaction-manager="transactionManager" />
实例代码:
@Transactional(propagation = Propagation.REQUIRED)
public boolean transfer(Long fromId, Long toId, double amount) {
return bankDao.transfer(fromId, toId, amount);
}
@Transactional注解
@Transactional属性
spring事务回滚规则
指示spring事务管理器回滚一个事务的推荐方法是在当前事务的上下文内抛出异常。spring事务管理器会捕捉任何未处理的异常,然后依据规则决定是否回滚抛出异常的事务。
默认配置下,spring只有在抛出的异常为运行时unchecked异常时才回滚该事务,也就是抛出的异常为RuntimeException的子类(Errors也会导致事务回滚),而抛出checked异常则不会导致事务回滚。
可以明确的配置在抛出那些异常时回滚事务,包括checked异常。也可以明确定义那些异常抛出时不回滚事务。
还可以编程性的通过setRollbackOnly()方法来指示一个事务必须回滚,在调用完setRollbackOnly()后你所能执行的唯一操作就是回滚。
属性 | 类型 | 描述 |
---|---|---|
value | String | 可选的限定描述符,指定使用的事务管理器 |
propagation | enum: Propagation | 可选的事务传播行为设置 |
isolation | enum: Isolation | 可选的事务隔离级别设置 |
readOnly | boolean | 读写或只读事务,默认读写 |
timeout | int (in seconds granularity) | 事务超时时间设置 |
rollbackFor | Class对象数组,必须继承自Throwable | 导致事务回滚的异常类数组 |
rollbackForClassName | 类名数组,必须继承自Throwable | 导致事务回滚的异常类名字数组 |
noRollbackFor | Class对象数组,必须继承自Throwable | 不会导致事务回滚的异常类数组 |
noRollbackForClassName | 类名数组,必须继承自Throwable | 不会导致事务回滚的异常类名字数组 |
事务配置驳杂, 就声明式和编程式配置就有多种,反而让人看得头疼,实际项目中,有的为了方便,更是多种风格并存;
如具体详情, 也可关于查看这边文章全面解析事务: http://www.cnblogs.com/crazylqy/p/5589589.html ;