spring进行声明式事务管理(annotation)
在使用注解的时候,首先得在配置文件bean.xml中添加命名空间:
xmlns:tx="http://www.springframework.org/schema/tx"
?
然后在xsi:schemaLocation中添加:
http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.5.xsd
?
再次引入事务管理者:
<tx:annotation-driven transaction-manager="txManager"/>
?
bean.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: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-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"><context:component-scan base-package="com.test"></context:component-scan><bean id="myDataSource" destroy-method="close"> <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/> <property name="url" value="jdbc:oracle:thin:@localhost:1521:oralsb"/> <property name="username" value="scott"/> <property name="password" value="tiger"/></bean><!-- annotation版 --><bean id="mySessionFactory" ref="myDataSource"/><property name="annotatedClasses"><list> <value>com.test.model.User</value> <value>com.test.model.Log</value></list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.Oracle9iDialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">true</prop><!-- <prop key="hibernate.hbm2ddl.auto">create</prop>--> </props> </property></bean> <!-- 定义事务管理者 --> <tx:annotation-driven transaction-manager="txManager"/> <bean id="txManager" ref="mySessionFactory" /></bean></beans>
?
实体类
User.java
package com.test.model;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.Table;@Entity@Table(name="t_user")public class User {private int id;private String name;@Id@GeneratedValuepublic int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}}?
Log.java
package com.test.model;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.Table;@Entity@Table(name = "t_log")public class Log {private int id;private String message;@Id@GeneratedValuepublic int getId() {return id;}public void setId(int id) {this.id = id;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}}?
接口
UserDAO.java
package com.test.dao;import com.test.model.User;public interface UserDAO {public void save(User user);}?
LogDAO.java
package com.test.dao;import com.test.model.Log;public interface LogDAO {public void save(Log log);}?
实现接口类
UserDAOImpl.java
package com.test.dao.impl;import javax.annotation.Resource;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.springframework.stereotype.Component;import com.test.dao.UserDAO;import com.test.model.User;@Component("userDAOImpl")public class UserDAOImpl implements UserDAO {private SessionFactory sessionFactory;public SessionFactory getSessionFactory() {return sessionFactory;}@Resourcepublic void setSessionFactory(SessionFactory sessionFactory) {this.sessionFactory = sessionFactory;}public void save(User user) {Session session = sessionFactory.getCurrentSession();session.save(user);}}?
LogDAOImpl.java
package com.test.dao.impl;import javax.annotation.Resource;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.springframework.stereotype.Component;import com.test.dao.LogDAO;import com.test.model.Log;@Component("logDAOImpl")public class LogDAOImpl implements LogDAO {private SessionFactory sessionFactory;public SessionFactory getSessionFactory() {return sessionFactory;}@Resourcepublic void setSessionFactory(SessionFactory sessionFactory) {this.sessionFactory = sessionFactory;}public void save(Log log) {Session session = sessionFactory.getCurrentSession();session.save(log);// spring默认RuntimeException的情况下事务会回滚// throw new RuntimeException("exception!");}}?
服务类
UserService.java
package com.test.service;import javax.annotation.Resource;import org.springframework.stereotype.Component;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;import com.test.dao.LogDAO;import com.test.dao.UserDAO;import com.test.model.Log;import com.test.model.User;@Component("userService")public class UserService {private UserDAO userDAO;private LogDAO logDAO;/** * 事务的传播特性: * 1.propagation默认值就是REQUIRED,表示在当前的环境中,别的地方调用这个方法,如果已经有了transaction,就用原来这个 * ,如果没有,就创建一个transaction(常用)。 * 2.propagation值为MANDATORY,表示在当前的环境中,别的地方调用这个方法必须有transaction,否则就报错。 * 3.propagation值为NESTED * ,相当于在原来的transaction中内嵌了一个transaction,别的地方调用这个方法,原来的transaction暂停,创建一个保存点 * ,方法新起一个transaction,执行完了,原来的transaction继续,内嵌的transaction如果回滚了, * 就会回滚到原来transaction的保存点(用的很少) * 4.propagation值为NEVER,表示在当前的环境中,别的地方调用这个方法不能有transaction,否则就报错。 * 5.propagation值为NOT_SUPPORTED * ,表示在当前的环境中,别的地方调用这个方法不能有transaction,否则先挂起原来的transaction */@Transactional(propagation = Propagation.REQUIRED)public void add(User user) {userDAO.save(user);Log log = new Log();log.setMessage("user save success!");logDAO.save(log);}public UserDAO getUserDAO() {return userDAO;}// 这里会找注解Component的值为:userDAOImpl的那个类@Resource(name = "userDAOImpl")public void setUserDAO(UserDAO userDAO) {this.userDAO = userDAO;}public LogDAO getLogDAO() {return logDAO;}@Resource(name = "logDAOImpl")public void setLogDAO(LogDAO logDAO) {this.logDAO = logDAO;}}?
Junit测试类
UserServiceTest.java
package com.test.service;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.test.model.User;public class UserServiceTest {@Testpublic void testAdd() throws Exception {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");UserService service = (UserService) applicationContext.getBean("userService");User u = new User();u.setName("张三");service.add(u);}}?