目录

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. file - 确定文件类型

    总览 file [ -bcnsvzL ] [ -f 命名文件 ] [ -m 幻数文件 ] file ... 描述 本手册页说明了3.27版本 file 命令的使用. File 命令试图检查每个参数以判 ...

  2. 设置meta标签 清除页面缓存,如:<meta http-equiv="Cache-Control" content="no-cache"/>

    <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" ...

  3. python_6_if

    _username='qi' _password='abc123' username=input("username:") password=input('password:') ...

  4. Linux命令的常用

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

  5. python生成随机数

    import random rnd=rand.uniform(0,10)

  6. detection in video and image

    video中的detection,背景更加复杂,目标更加不聚焦,同时由于图片分辨率低于图像,因此更加难做. image中的Detection,背景相对简单些,目标更加聚焦,同时图片分辨率高,因此更加容 ...

  7. 1025: [SCOI2009]游戏

    Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2727  Solved: 1794[Submit][Status][Discuss] Descripti ...

  8. Jquery 就是怎么取得一个select的当前值

    <select id="cursel">: <option value="1">值1</option>: <optio ...

  9. python3 包的发布

    发布流程大概如下 1. 首先需要有一个python包,就是一个文件夹,但是此文件夹下面有__init__.py文件,里面内容是 现在要发布包TestMsg,这就是一个python包.在同级目录下新建s ...

  10. 51NOD:1639-绑鞋带

    传送门:https://www.51nod.com/onlineJudge/submitDetail.html#!judgeId=475129 1639 绑鞋带 基准时间限制:1 秒 空间限制:131 ...