编程式事务
/**
* 1. 根据DataSource去创建事务管理器
* 构造方法 , 参数1. DataSource
*/
DataSourceTransactionManager txManager = new DataSourceTransactionManager(getDataSource());
/**
* 2. 创建事务模版对象, 并将事务管理器传递给模版
*/
TransactionTemplate ttlate = new TransactionTemplate(txManager); /**
* 3. 通过事务模版 , 执行事务, 并指定事务的回调函数
*/
Boolean flag = ttlate.execute(new TransactionCallback<Boolean>() { /**
* 我们要处理的JDBC操作, 可以放到这个方法中, 在这个方法里的所有JDBC操作, 将视为一个事务
*
* 这个方法, 如何认定事务是否应该提交 :
*
* 当方法中出现异常, 则表示事务执行失败 ,
* 如果异常进行了处理, 则事务执行成功!
*/
@Override
public Boolean doInTransaction(TransactionStatus status) {
try{ getJdbcTemplate().update("update book set bookname=? where bookid=?", "西游记",10002);
if(1==2){
throw new RuntimeException("停电了, 哈哈哈");
}
getJdbcTemplate().update("update book set bookname=? where bookid=?", "红楼梦",10003);
return true;
}catch(Exception e){
e.printStackTrace();
//处理了异常 , 没事了
//加入回滚标记 ( 本次事务不提交 )
status.setRollbackOnly();
return false; }
}
});
System.out.println("事务执行的结果:"+flag);
声明式事务
相较于编程式的事务 ,有利有弊 !
优点:
是一种aop的编程思想, 给一段代码添加事务, 无需修改原代码
缺点:
因为采用了注解, 注解的最小范围只能给类的成员 , 也就是说, 声明时的事务 ,最小的处理范围是一个方法 !
使用步骤:
1. 向容器中添加事务的管理对象
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg index="0" ref="dataSource"></constructor-arg>
</bean> 2. 开启事务的扫描 , 指定事务管理器 <tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/> 3. 在具体要被执行事务的方法上, 添加注解@Transactional即可
@Transactional也可以添加到类上,表示对该类的所有方法使用事务
@Transactional注解的属性
@Transactional注解标记有以下属性,在使用时
可以根据需要做特殊设定。
propagation: 设置事务传播
isolation : 设置事务隔离级别
readOnly : 设置为只读,还是可读写
rollbackFor : 设置遇到哪些异常必须回滚
noRollbackFor : 设置遇到哪些异常不回滚
看一个Demo:
User类:
package cn.wxg.bean; public class User { private int id;
private String name;
private String password;
public User() {
super();
}
public int getId() {
return id;
}
public User(int id, String name, String password) {
super();
this.id = id;
this.name = name;
this.password = password;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", password=" + password + "]";
} }
User.java
Dao类:
package cn.wxg.dao; import java.util.List; import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate; import cn.wxg.bean.User; public class UserDao extends JdbcDaoSupport { @Transactional
public void test2(List<User> user){
String sql1="update test_user set password=? where name=?";
String sql2="update test_user set password=? where name=?"; getJdbcTemplate().update(sql1, user.get(0).getPassword(),user.get(0).getName());
getJdbcTemplate().update(sql2, user.get(1).getPassword(),user.get(1).getName());
} public boolean updateUser(List<User> user){
String sql1="update test_user set password=? where name=?";
String sql2="update test_user set password=? where name=?"; //声明事务管理组件
DataSourceTransactionManager dstt = new
DataSourceTransactionManager(getDataSource());
//声明事务组件
TransactionTemplate tt = new
TransactionTemplate(dstt);
//执行事务
Boolean res = tt.execute(new TransactionCallback<Boolean>(){ @Override
public Boolean doInTransaction(TransactionStatus status){
try{
getJdbcTemplate().update(sql1, user.get(0).getPassword(),user.get(0).getName());
getJdbcTemplate().update(sql2, user.get(1).getPassword(),user.get(1).getName());
return true;
}catch(Exception e){
status.setRollbackOnly();//回滚
}
return false;
}
});
return res;
}
}
UserDao
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:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd"> <bean id="database" class="org.apache.commons.dbcp.BasicDataSource">
<!-- 驱动地址 -->
<property name="driverClassName" value="oracle.jdbc.OracleDriver"></property>
<!-- 数据库的连接地址 -->
<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"></property>
<!-- 数据库的帐号 -->
<property name="username" value="system"></property>
<!-- 数据库的密码 -->
<property name="password" value="517839"></property>
</bean> <bean id="userDao" class="cn.wxg.dao.UserDao">
<!--
在调用set方法进行赋值,
Spring容器是通过反射技术 ,根据我们传递的name参数 , 得到对应的set方法名称, 将其调用
-->
<property name="dataSource" ref="database"></property>
</bean> <!--配置DataSourceTransactionManager,事务管理着对象|-->
<bean id="txManage" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg index="0" ref="database"></constructor-arg>
</bean> <!--开启事务扫描-->
<tx:annotation-driven transaction-manager="txManage" proxy-target-class="true"/>
<!--文件扫描-->
<context:component-scan base-package="cn"></context:component-scan> </beans>
applicationContext.xml
测试类:
package cn.wxg.text; import java.util.ArrayList;
import java.util.List; import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import cn.wxg.bean.User;
import cn.wxg.dao.UserDao; public class UserDaoTest { @Test
public void testName1() throws Exception {
//加载配置文件
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = ac.getBean("userDao", UserDao.class);
User user1=new User(1001,"jame","987654321");
User user2=new User(1002,"locy","987654321");
List<User> users=new ArrayList<User>();
users.add(user1);
users.add(user2);
// System.out.println(userDao.updateUser(users));
userDao.test2(users); }
}
UserDaoTest.java