目录

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. Dll注入:x86/X64 SetThreadContext 注入

    在<Windows核心编程>第七章说到了线程优先级等知识,其中谈到了ThreadContext线程上下背景文. 其中介绍了GetThreadContext函数来查看线程内核对象的内部,并获 ...

  2. linux 命令——54 ping(转)

    Linux系统的ping 命令是常用的网络命令,它通常用来测试与目标主机的连通性,我们经常会说“ping一下某机器,看是不是开着”.不能打开网页时会说“你先ping网关地 址192.168.1.1试试 ...

  3. Spark性能优化——和shuffle搏斗

    Spark的性能分析和调优很有意思,今天再写一篇.主要话题是shuffle,当然也牵涉一些其他代码上的小把戏. 以前写过一篇文章,比较了几种不同场景的性能优化,包括portal的性能优化,web se ...

  4. 浅谈 import / export

    import { ngModule } from '@angular/core'; import { AppComponent } from './app.component'; export cla ...

  5. python 基础之列表切片内置方法

    列表操作 c=['cx','zrd','ajt','dne'] #定义一个列表,有4个元素 #增删改查 print(c[3]) #从0计数 测试 D:\python\python.exe D:/unt ...

  6. CUDA:Supercomputing for the Masses (用于大量数据的超级计算)-第九节

    原文链接 第九节:使用CUDA拓展高等级语言 Rob Farber 是西北太平洋国家实验室(Pacific Northwest National Laboratory)的高级科研人员.他在多个国家级的 ...

  7. java菜鸟的Python学习之路(1)

    学习一门新的语言,应当抓住语言的共有特性,这样容易触类旁通,学习起来也十分的快捷愉悦 而语言的特性大约有以下元素 变量定义与类型 算术符号与逻辑符号 for 循环与 while 循环 数组,线性表等一 ...

  8. 五、Linux 远程登录

    Linux 远程登录 Linux一般作为服务器使用,而服务器一般放在机房,你不可能在机房操作你的Linux服务器. 这时我们就需要远程登录到Linux服务器来管理维护系统. Linux系统中是通过ss ...

  9. 三、MySQL PHP 语法

    MySQL PHP 语法 MySQL 可应用于多种语言,包括 PERL, C, C++, JAVA 和 PHP. 在这些语言中,Mysql在PHP的web开发中是应用最广泛. 在本教程中我们大部分实例 ...

  10. ob缓存的基本使用

    在页面 加载的时候 如果 图片 很多 很大 会造成页面的阻塞降低用户体验 我们在点击页面的时候可以使用OB缓存 整个页面, 当用户点击的时候直接请求的是我们预先准备好的html页面 .也降低了我们数据 ...