<!-- 创建sessionFactory -->
<bean>
<property ref="dataSource"/>
<property>
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
</props>
</property>
<!-- 实体类映射文件 -->
<property>
<list>
<value>classpath*:/domain/*.hbm.xml</value>
</list>
</property>
<property>
<value>domain</value>
</property>
<!-- 实体类 -->
<property>
<list>
<value>domain.UserEntity</value>
</list>
</property>
</bean>
<!-- 创建声明式事务管理 -->
<bean>
<property ref="sessionFactory"/>
</bean>
<!-- 事务通知 -->
<tx:advice transaction-manager="transactionManager">
<tx:attributes>
<!-- propagation配置传播行为,isolation配置隔离方式,表示在方法存在事务的时候直接使用,不存在则创建一个新事务,隔离级别为一个事务可以读取另外一个已提交事务的内容, -->
<tx:method propagation="REQUIRED" isolation="READ_COMMITTED"/>
</tx:attributes>
</tx:advice>
<!-- aop织入通知 -->
<aop:config>
<aop:pointcut expression="execution(* service.serviceImpl.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOption"/>
</aop:config>
</beans>
web.xml (配置session拦截器,他将为每个请求绑定一个session,这个session是hibernateSession和,httpSession不一样,这样他可以有spring自动管理,无需手动开关)
<!-- 为每个请求过程绑定一个HibernateSession,它将由spring自动管理,无需手动开启和关闭 -->
<filter>
<filter-name>openSessionInterceptor</filter-name>
<filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>openSessionInterceptor</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
在未使用事务管理的时候,同一个事务内的两个数据库操作,一个成功了,就会对数据库产生影响,如果两个操作是互相对应的,比如一个是增加数值,一个是减少数值,如果两个操作只做个一个,那么数据将不完整,出现异常(当然这种异常数据是不会报错的),但是添加了事务管理之后,就可以防止这种问题,事务的原子性:一件事情要么全做要么不做,一旦有操作失败,那么事务将进行rallback()回滚,撤销之前的所有事务操作。
如下图:
即使执行了语句,但是后面遇到了1/0的数值计算异常,那么 事务会进行回滚,撤销操作,数据库数据还是保持原样。事务一旦commit成功,再执行rollback回滚已经没有效果了。
测试代码:
public int updateUserInfo() {
Session session = sessionFactory.getCurrentSession();
String hql = "update UserEntity user set user.username='改1次' where user.id=1";
session.createQuery(hql).executeUpdate();
hql = "update UserEntity user set user.username='改2次' where user.id=1";
session.createQuery(hql).executeUpdate();
List<UserEntity> usersList = session.createQuery("from UserEntity ").list();
for (UserEntity u:usersList){
System.out.println(u.getUsername()+" : "+u.getCreateTime());
}
int i = 1/0;
return 0;
}