目录

1 sessionFactory 注入HibernateTransactionManager

2 XML配置的配置

3 添加annotation-driven

4 引入JAR包

5在service层添加事务声明的注释

6 改写数据库的实现类的方法,不再需要开始事务和提交事务,并且使用getCurrentSession

7 编写测试类通过

通过Spring的事务管理可以实现,对事务的统一管理,并且写节省冗余代码,结构清晰 抓到runtimeException进行回滚,

事务的策略Springl默认是required

1 sessionFactory注入org.springframework.orm.hibernate4.HibernateTransactionManager

    <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory"></property>
</bean>

2 引入XML配置

1 xmlns:tx="http://www.springframework.org/schema/tx"

2 http://www.springframework.org/schema/tx
3 http://www.springframework.org/schema/tx/spring-tx.xsd

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
">

3 添加annotation-driven

<tx:annotation-driven transaction-manager="txManager" />

4 引入JAR包 

aopalliance-1.0

5在service层添加事务声明的注释

    @Transactional
public void add(User user) {
userDao.save(user);
}

6 改写数据库的实现类的方法,不再需要开始事务和提交事务,并且使用getCurrentSession

    public void save(User user) {
System.out.println(user.getName()+"-->"+user.getRemark()+" save --调用UserDaoImpl2!");
Session s = mySessionFactory.getCurrentSession();
s.save(user);
}

7 测试一下

@Test
public void testAdd() {
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("beans.xml");
UserServiceImpl UserServiceImpl = (UserServiceImpl)app.getBean("userServiceImpl");
UserServiceImpl.add(user);//调用方法
}

8 测试通过

下面会详细给出代码

9编译常见的报错信息

1  Add CGLIB to the class path or specify proxy interfaces.
引入 cglib-nodep-2.1_3.jar

2 org.hibernate.HibernateException: save is not valid without active transaction
  去掉sessionFactory的property的配置 hibernate.current_session_context_class=thread

3 org.hibernate.MappingException: Unknown entity: com.entity.Log

sessionFactory里需要配置property的实体类

<property name="annotatedClasses">
<list>
<value>com.entity.User</value>
<value>com.entity.Log</value>
</list>
</property>

--------------------------------------------------------------------------------------------

Spring的事务管理具体的应用

例如 有一个服务service是完成以下功能

1 保存一个用户信息进A表,保存成功后打印一条日志进入B表

2 如果日志打印报错则插入的A表的用户回滚

完整的代码

XML

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
"> <context:component-scan base-package="com.*"></context:component-scan>
<tx:annotation-driven transaction-manager="txManager" /> <bean id="mappings"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath:jdbc.properties</value>
</property>
</bean> <!-- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">-->
<!-- <property name="driverClassName" value="com.mysql.jdbc.Driver"/>-->
<!-- <property name="url" value="jdbc:mysql://localhost:3306/spring"/>-->
<!-- <property name="username" value="root"/>-->
<!-- <property name="password" value="root"/>-->
<!-- </bean>--> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean> <bean id="mySessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.entity.User</value>
<value>com.entity.Log</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=true
<!-- hibernate.current_session_context_class=thread-->
</value>
</property>
</bean> <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory"></property>
</bean> </beans>

service

package com.serviceImpl;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import com.dao.LogDao;
import com.dao.UserDao;
import com.entity.Log;
import com.entity.User;
@Component
public class UserServiceImpl { private UserDao userDao;
private LogDao logDao; @Transactional
public void add(User user) {
userDao.save(user);
Log log = new Log();
log.setContent(user.getName());
logDao.save(log);
} public void update(User user) {
userDao.update(user);
}
public void init() {// 初始方法
System.out.println("init");
}
public void destroy() {// 销毁方法
System.out.println("destory");
}
public UserDao getUserDao() {
return userDao;
} @Resource(name="userDaoImpl2")
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
} public LogDao getLogDao() {
return logDao;
}
@Resource
public void setLogDao(LogDao logDao) {
this.logDao = logDao;
}
}

UserDaoImpl2

package com.daoImpl;

import javax.annotation.Resource;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import com.dao.UserDao;
import com.entity.User;
@Component
public class UserDaoImpl2 implements UserDao{
SessionFactory mySessionFactory; public void save(User user) {
System.out.println(user.getName()+"-->"+user.getRemark()+" save --调用UserDaoImpl2!");
Session s = mySessionFactory.getCurrentSession();
s.save(user);
} public void update(User user) {
System.out.println(user.getName()+"-->"+user.getRemark()+" update --调用UserDaoImpl2!");
Session s = mySessionFactory.getCurrentSession();
s.update(user);
} public SessionFactory getMySessionFactory() {
return mySessionFactory;
} @Resource
public void setMySessionFactory(SessionFactory mySessionFactory) {
this.mySessionFactory = mySessionFactory;
} }

logImpl

package com.daoImpl;

import javax.annotation.Resource;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Component; import com.dao.LogDao;
import com.entity.Log;
@Component
public class LogDaoImpl implements LogDao{
SessionFactory mySessionFactory; public void save(Log log) {
Session s = mySessionFactory.getCurrentSession();
s.save(log);
}
public SessionFactory getMySessionFactory() {
return mySessionFactory;
} @Resource
public void setMySessionFactory(SessionFactory mySessionFactory) {
this.mySessionFactory = mySessionFactory;
} }

logDao,userDao

package com.dao;

import com.entity.Log;
import com.entity.User; public interface LogDao {
public void save(Log log);
}
package com.dao;

import com.entity.User;

public interface UserDao {
public void save(User user);
public void update(User user);
}

实体类

package com.entity;

import javax.persistence.Entity;
import javax.persistence.Id; @Entity
public class User {
@Id
private int id;
private String name;
private String remark; public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
package com.entity;

import javax.persistence.Entity;
import javax.persistence.Id; @Entity
public class Log {
@Id
private int id;
private String content; public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}

最后是测试类

package com.serviceImpl.test;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.entity.User;
import com.serviceImpl.UserServiceImpl; public class UserServiceImplTest {
User user; @Before
public void setUp() throws Exception {
user = new User();
user.setName("ttN");
user.setRemark("ttR");
} @Test
public void testAdd() {
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("beans.xml");
UserServiceImpl UserServiceImpl = (UserServiceImpl)app.getBean("userServiceImpl");
UserServiceImpl.add(user);//调用方法
}
}

执行结果

ttN-->ttR save --调用UserDaoImpl2!
Hibernate: insert into User (name, remark, id) values (?, ?, ?)
Hibernate: insert into Log (content, id) values (?, ?)

接下来测试一下,如果写入日志失败是否能够回滚

模拟 模拟日志的ID重复了,导致失败

    @Transactional
public void add(User user) {
userDao.save(user);
Log log = new Log();
log.setId();
logDao.save(log);
}

测试类

@Before
public void setUp() throws Exception {
user = new User();
user.setName("testRollBack");
user.setRemark("testRollBack");
} @Test
public void testAdd() {
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("beans.xml");
UserServiceImpl UserServiceImpl = (UserServiceImpl)app.getBean("userServiceImpl");
UserServiceImpl.add(user);//调用方法
}

执行结果

testRollBack-->testRollBack save --调用UserDaoImpl2!
Hibernate: insert into User (name, remark, id) values (?, ?, ?)
Hibernate: insert into Log (content, id) values (?, ?)

报错信息

org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; 
Caused by: java.sql.SQLException: Column 'content' cannot be null

存入的USER数据已经回滚

实体类其实还可以通过自动扫描的方式获取

<!--  <property name="annotatedClasses">-->
<property name="packagesToScan">
<list>
<value>com.entity</value>
<!-- 这些都不需要一个一个写了 <value>com.entity.User</value>-->
<!-- <value>com.entity.Log</value>-->
</list>
</property>

Spring整合hibernate -声明事务管理的更多相关文章

  1. Spring整合hibernate4:事务管理

    Spring整合hibernate4:事务管理 Spring和Hibernate整合后,通过Hibernate API进行数据库操作时发现每次都要opensession,close,beginTran ...

  2. Spring整合hibernate4:事务管理[转]

    Spring和Hibernate整合后,通过Hibernate API进行数据库操作时发现每次都要opensession,close,beginTransaction,commit,这些都是重复的工作 ...

  3. Spring+SpringMVC+Hibernate小案例(实现Spring对Hibernate的事务管理)

    原文地址:https://blog.csdn.net/jiegegeaa1/article/details/81975286 一.工作环境 编辑器用的是MyEclipse,用Mysql数据库,mave ...

  4. Spring整合Hibernate--声明式事务管理

    Spring指定datasource 1. 新建jdbc.properties文件: jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc: ...

  5. 【Java EE 学习 53】【Spring学习第五天】【Spring整合Hibernate】【Spring整合Hibernate、Struts2】【问题:整合hibernate之后事务不能回滚】

    一.Spring整合Hibernate 1.如果一个DAO 类继承了HibernateDaoSupport,只需要在spring配置文件中注入SessionFactory就可以了:如果一个DAO类没有 ...

  6. spring整合hibernate

    spring整合hibernate包括三部分:hibernate的配置.hibernate核心对象交给spring管理.事务由AOP控制 好处: 由java代码进行配置,摆脱硬编码,连接数据库等信息更 ...

  7. 使用Spring整合Hibernate,并实现对数据表的增、删、改、查的功能

    1.1 问题 使用Spring整合Hibernate,并实现资费表的增.删.改.查. 1.2 方案 Spring整合Hibernate的步骤: 1.3 步骤 实现此案例需要按照如下步骤进行. 采用的环 ...

  8. spring整合hibernate时报错:org.hibernte.engine.transaction.spi.transactioncontext

    错误提示:Caused by:java.lang.ClassNotFoundException: org.hibernte.engine.transaction.spi.transactioncont ...

  9. Maven环境下搭建SSH框架之Spring整合Hibernate

    © 版权声明:本文为博主原创文章,转载请注明出处 1.搭建环境 Spring:4.3.8.RELEASE Hibernate:5.1.7.Final MySQL:5.7.17 注意:其他版本在某些特性 ...

随机推荐

  1. hadoop2.4 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable

    在Ubuntu上安装完hadoop2.4以后,使用以下命令: hadoop fs -ls // :: WARN util.NativeCodeLoader: Unable to load native ...

  2. java Vamei快速教程21 事件响应

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在GUI中,我们看到了如何用图形树来组织一个图形界面.然而,这样的图形界面是静态的 ...

  3. IOS 核心动画(Core Animation)

    Core Animation,中文翻译为核心动画,它是一组非常强大的动画处理API,使用它 能做出非常炫丽的动画效果,而且往往是事半功倍.也就是说,使用少量的代码就 可以实现非常强大的功能. Core ...

  4. 如何解决EXCEL中的科学计数法

    EXCEL虽然能够有效的处理数据,尤其是数字的计算.但是,在单元格中输入数字的时候,很多时候都会受到科学计算法的困扰. 当单元格中输入的数字,超过11位时,就会自动变成科学计数法.无论您怎么调整列的宽 ...

  5. 【转】 Solr的SolrCloud与Master-slave主从模式对比

    第一印象 SolrCloud是Solr4.0引入的,主要应对与商业场景.它很像master-slave,却能自动化的完成以前需要手动完成的操作.利用ZooKeeper这个工具去监控整个Solr集群,以 ...

  6. OneNote- 面经

  7. Linux命令的常用

    使用chown命令更改文件拥有者 在 shell 中,可以使用chown命令来改变文件所有者.chown命令是change owner(改变拥有者)的缩写.需要要注意的是,用户必须是已经存在系统中的, ...

  8. 关于小程序 scroll-view中设置scroll-top无效 和小说图书阅读进度条小案例

    在最近的项目有做到关于小说阅读的进度条功能,其中用到scroll-view和slider组件,发现scroll-view中的scroll-top在设置值后无效,出现这种情况大概是以下几种问题: 1.s ...

  9. Java 获取Web项目相对webapp地址

    例如, import java.io.File; import java.io.FileInputStream; import javax.servlet.http.HttpServletReques ...

  10. js数据结构与算法--递归

    递归,函数自己调用自己 return 返回值, 后面的代码不执行 function fn(num){ console.log(num) if(num == 0){ return; } fn(num-1 ...