事务管理必须jar包
spring-tx-4.0.2.RELEASE.jar
使用Annotation进行声明式事务管理的配置
事务管理的原理是使用切面注入,所以得配置aop。
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
<!--配置事务管理 -->
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:annotation-config/>
<context:component-scan base-package="com.login"/>
<context:property-placeholder location="jdbc.properties"/>
<bean id="dataSource" class="org.apache.commons.dbcp2.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="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan">
<list>
<value>com.login.model</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=true
hibernate.format_sql=true
hibernate.hbm2ddl.auto=update
<!--Spring默认是使用线程方式创建。不配置或者指明使用Spring的默认线程-->
hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext
</value>
</property>
</bean>
<!--大坑!!!我使用的spring4+hibernate5。
使用hibernate5.0版本的核心jar包会报Could not open Hibernate Session for transaction; nested exception is java.lang.NoClassDefFoundError: org/hibernate/engine/transaction/spi/TransactionContext异常。
按道理配置修改为class="org.springframework.orm.hibernate5.HibernateTransactionManager"可以,
但是这是个bug,得使用hibernate-core-4.2.4.Final.jar包替换hibernate-core-5.0.0.Final.jar。
-->
<!--注入事务管理,这里注入了sessionFactory,而sessionFactory里面配置了hibernate和注入了dataSource。-->
<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 添加事务管理的annotation驱动-->
<tx:annotation-driven transaction-manager="txManager"/>
</beans>
声明式事务管理操作
当用户添加时,往日志中添加条消息。
根据事务catch到异常的是否来回滚事务还是提交事务。
事务处理应放在service层(业务逻辑层)
1.日志实体类
@Entity
@Table(name="T_log")
public class Log {
private int id;
private String msg;
public Log(){
}
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
2.日志数据访问层(dao)
public interface LogDAO {
public void save(Log log);
}
3.daoImpl
@Component
public class LogDAOImpl implements LogDAO {
private SessionFactory sessionFactoy;
public SessionFactory getSessionFactoy() {
return sessionFactoy;
}
@Resource
public void setSessionFactoy(SessionFactory sessionFactoy) {
this.sessionFactoy = sessionFactoy;
}
//方法中直接save,事务管理放在业务逻辑层
@Override
public void save(Log log) {
Session s = sessionFactoy.getCurrentSession();
s.save(log);
System.out.println("log add to mysql...");
}
}
4.业务逻辑层
@Component("userService")
public class UserService {
private UserDAO userDAO ;
private LogDAO logDAO;
public UserService(){
}
public LogDAO getLogDAO() {
return logDAO;
}
@Resource
public void setLogDAO(LogDAO logDAO) {
this.logDAO = logDAO;
}
public UserDAO getUserDAO() {
return userDAO;
}
@Resource(name="u")
public void setUserDAO( UserDAO userDAO) {
this.userDAO = userDAO;
}
@Transactional
public void add(User u){
userDAO.save(u);
Log log = new Log();
log.setMsg("a user add");
logDAO.save(log);
}
}
使用@Tarnsactional注解进行声明式事务管理。
假如catch到异常user和log都不能添加到数据库。