作用:保证数据库的完整性。
事务概念:在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。
举例:银行转账。A账户向B账户转1000元,这时A应当减少1000元,而B增加1000元,这是正确的处理结果。
银行系统出错,会出现两种情况:
(1)A账户少了1000元,而B的账户却没有增加1000元;
(2)A账户没有减少1000元,而这时B的账户却增加了1000元。
客户和银行都不愿看到这种情形,。那么有没有措施保证转帐得顺利进行呢?这种措施就是——数据库事务管理机制。
相关内容:
Spring的数据库编程(不涉及事务管理情况),
编程式事务管理 a.基于底层API编程事务管理 b.基于TransactionTemplate编程事务管理
声明式事务管理。
Spring的数据库管理:
目录结构:
配置文件:
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
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">
<!-- 通过扫描器扫描包(或子包),将带有注解的类注册为Bean -->
<context:component-scan base-package="jdbc"/>
<!--配置数据源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!-- 数据库驱动 -->
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<!-- 连接数据库ulr -->
<property name="url" value="jdbc:mysql://localhost:3306/user?characterEncoding=utf8"></property>
<!-- 用户名 -->
<property name="username" value="root"></property>
<!-- 用户密码 -->
<property name="password" value="123456"></property>
</bean>
<!-- 配置JDBC模板 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
实体类:
package jdbc;
public class MyUser {
private Integer id;
private String name;
private String sex;
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return id+" "+name+" "+sex+" "+age;
}
}
数据库访问层:
package jdbc;
import java.util.List;
public interface TestDao {
public int update(String sql,Object[] param);
public List<MyUser> query(String sql,Object[] param);
}
package jdbc;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
@Repository("testDao")
public class TestDaoImp implements TestDao{
@Autowired
private JdbcTemplate jdbcOperate;
@Override
public int update(String sql, Object[] param) {
return jdbcOperate.update(sql, param);
}
@Override
public List<MyUser> query(String sql, Object[] param) {
// TODO Auto-generated method stub
RowMapper<MyUser> mapper=new BeanPropertyRowMapper<MyUser>(MyUser.class);
return jdbcOperate.query(sql, mapper,param);
}
}
测试类:
package Test;
import java.util.Iterator;
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import jdbc.MyUser;
import jdbc.TestDao;
public class TestJdbc {
public static void main(String[] args) {
//获取Application容器
ApplicationContext appcon=new ClassPathXmlApplicationContext("ApplicationContext.xml");
//获取增强后的数据库操作对象
TestDao jdbcop= (TestDao) appcon.getBean("testDao");//param表示参数,可以指代一组数据
/*
* =======================数据更新----插入
*/
//数据插入sql语句
String insertSql="insert into user values(?,?,?,?)";
//数据paramd的值与insertsql中的?一一对应
Object param1[]= {1,"chaokaidi1","男",33};
Object param2[]= {3,"chaokaidi2","男",44};
Object param3[]= {6,"chaokaidi3","男",21};
Object param4[]= {9,"chaokaidi4","女",34};
//添加用户
jdbcop.update(insertSql, param1);
jdbcop.update(insertSql, param2);
jdbcop.update(insertSql, param3);
jdbcop.update(insertSql, param4);
System.out.println("更新!!!");
/*
* ========================数据查询
*/
String querySql="select * from user";
List<MyUser> MyUserList=jdbcop.query(querySql, null);
for(Iterator iterator = MyUserList.iterator(); iterator.hasNext();) {
MyUser myUser = (MyUser) iterator.next();
System.out.println(myUser.toString());//duplicate:完全一样的
}
}
}
编程事务管理——基于底层API(PlatformTransactionManager,TransactionDefinition和TransactionStatus接口)
注:DataSourceTransactionManager实现了PlatformTransactionManager接口
DefaultTransactionDefinition实现了TransactionDefinition接口
配置文件添加:
<!-- 添加事务回滚 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
测试代码修改:
package Test;
import java.util.Iterator;
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import jdbc.MyUser;
import jdbc.TestDao;
public class TestJdbc {
public static void main(String[] args) {
//获取Application容器
ApplicationContext appcon=new ClassPathXmlApplicationContext("ApplicationContext.xml");
//获取增强后的数据库操作对象
TestDao jdbcop= (TestDao) appcon.getBean("testDao");//param表示参数,可以指代一组数据
DataSourceTransactionManager tm=(DataSourceTransactionManager) appcon.getBean("txManager");
TransactionDefinition definition=new DefaultTransactionDefinition();
//开启事务
TransactionStatus ts=tm.getTransaction(definition);
String message="执行成功";
try {
/*
* =======================数据更新----插入
*/
//数据插入sql语句
String insertSql="insert into user values(?,?,?,?)";
//数据paramd的值与insertsql中的?一一对应
Object param1[]= {1,"chaokaidi1","男",33};
Object param2[]= {3,"chaokaidi2","男",44};
Object param3[]= {6,"chaokaidi3","男",21};
Object param4[]= {9,"chaokaidi4","女",34};
//添加用户
jdbcop.update(insertSql, param1);
jdbcop.update(insertSql, param2);
jdbcop.update(insertSql, param3);
jdbcop.update(insertSql, param4);
System.out.println("更新!!!");
/*
* ========================数据查询
*/
String querySql="select * from user";
List<MyUser> MyUserList=jdbcop.query(querySql, null);
for(Iterator iterator = MyUserList.iterator(); iterator.hasNext();) {
MyUser myUser = (MyUser) iterator.next();
System.out.println(myUser.toString());//duplicate:完全一样的
}
tm.commit(ts);
}catch (Exception e) {
tm.rollback(ts);
message="事务进行回滚";
}finally {
System.out.println(message);
}
}
}
编程事务管理——基于TransactionTemplate
注:TransactionTemplate的execute方法有一个TransactionCallbac接口类型的参数,该接口定义了doInTransaction方法,通过内部内类的方式实现TransactionCallback接口,并在doIntTransaction方法内书写业务逻辑代码。
配置文件添加:
<!-- 为事务管理器txManager创建transcationTemplate -->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="txManager"></property>
</bean>
测试代码修改:
package Test;
import java.util.Iterator;
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import jdbc.MyUser;
import jdbc.TestDao;
public class TestJdbc {
public static void main(String[] args) {
//获取Application容器
ApplicationContext appcon=new ClassPathXmlApplicationContext("ApplicationContext.xml");
//获取增强后的数据库操作对象
TestDao jdbcop= (TestDao) appcon.getBean("testDao");//param表示参数,可以指代一组数据
//==============基于底层API进行事务处理
// DataSourceTransactionManager tm=(DataSourceTransactionManager) appcon.getBean("txManager");
// //默认事务定义
// TransactionDefinition definition=new DefaultTransactionDefinition();
// //开启事务
// TransactionStatus ts=tm.getTransaction(definition);
//=================================================
String message="执行成功";
TransactionTemplate template1 = (TransactionTemplate) appcon.getBean("transactionTemplate");
template1.execute(new TransactionCallback<Object>() {
@Override
public Object doInTransaction(TransactionStatus arg0) {
String message="执行成功!!";
try {
/*
* =======================数据更新----插入
*/
//数据插入sql语句
String insertSql="insert into user values(?,?,?,?)";
//数据paramd的值与insertsql中的?一一对应
Object param1[]= {20,"chaokaidi1","男",33};
Object param2[]= {3,"chaokaidi2","男",44};
Object param3[]= {6,"chaokaidi3","男",21};
Object param4[]= {9,"chaokaidi4","女",34};
//添加用户
jdbcop.update(insertSql, param1);
jdbcop.update(insertSql, param2);
jdbcop.update(insertSql, param3);
jdbcop.update(insertSql, param4);
System.out.println("更新!!!");
/*
* ========================数据查询
*/
String querySql="select * from user";
List<MyUser> MyUserList=jdbcop.query(querySql, null);
for(Iterator iterator = MyUserList.iterator(); iterator.hasNext();) {
MyUser myUser = (MyUser) iterator.next();
System.out.println(myUser.toString());//duplicate:完全一样的
}
System.out.println("执行成功!!!");
return null;
}catch (Exception e) {
message="事务回滚!!";
}
return message;
}
});
}
}