在数据库操作中,事务处理十分重要,在Spring中提供了强大的事务处理功能,不仅可以用编程的方式实现,而且可以使用声明方式实现,通过使用Spring,可以在简单的JavaBean中使用类似EJB的声明式事务管理。
在数据库操作中,事务处理是经常用到的,例如在银行业务中,A给B账户转账10万RMB,首先要从A的账户中减去10万,然后再给B的账户增加10万,整个操作是一个整体,这就是一个简单的事务,在这个事务中必须保证操作的完整性,如果其中一部出错全部都不执行,从而保证这个业务的正确性和完整性。
在JDBC中也支持事务操作,一般情况下,事务的操作需要进行下面3步操作:
① 把数据库连接对象的自动提交SQL操作的属性关闭;
② 执行一些列数据库操作,如果成功就提交事务;
③ 如果事务中的操作没有全部成功,就回滚整个事务。
Connection conn = null;
Statement stat = null;
//加载数据库驱动类
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance();
//数据库连接URL
String url = "jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=Students";
//数据库用户名
String user = "sa";
//数据库密码
String password = "123454";
//根据数据库参数取得一个数据库连接
conn = DriverManager.getConnection(url,user,password);
conn.setAutoCommit(false);
try{
stat = conn.createStatement();
String insertSql = "insert into student(name,age,gender) values('李四',23,'男')";
stat.execute(insertSql);
String updateSql = "update student set age = '99岁' where name = '张三'"
stat.execute(updateSql);
conn.commit();
}catch(Exception ex){
conn.rollback();
System.out.pring(ex.getMessage());
}
上面这段代码是在JDBC中处理事务的一般步骤,首先吧Connection对象自动提交SQL操作的属性设置为false,这样之后在执行提交命令以后才会把SQL操作真正提交到数据库中,在进行数据库操作的时候,如果在操作过程中没有异常出现,就用commit()方法手动提交执行的数据库SQL操作,如果有异常出现就用rollback()方法撤销这些数据库操作,从而保证数据库操作的完整性。
在Spring中,并没有直接管理事务,而是内置了多种职务管理器,将事务管理的任务委托给这些事务管理器进行处理,每种事务管理器都是针对某种特定平台的,例如使用JDBCDataSource进行数据库操作的时候可以使用DataSourceTransactionManager进行事务处理,使用Hibernate的时候可以使用HibernateTransactionManager进行事务管理。他俩的区别详见:http://bjyzxxds.iteye.com/blog/427309
Spring中提供的事务都对不同的平台进行了不同的处理,从而提供给用户统一的事务管理API,所以使用Spring进行事务处理的时候,只需要处理Spring事务即可,无需关心针对平台特性,这些平台的差异在Spring中已经被提前处理。下面是Spring可选择的事务管理器:
上文提到过Spring既可以编程式事务管理,也可以声明式事务管理,下面就举一个声明式事务管理的例子:
Spring中的声明式事务管理是使用AOP框架实现的,可以在程序中需要事务管理的地方用AOP的方式引入事务管理。下面的实例程序中,展示了如何在Spring中实现声明式事务管理。
package trans.config;
public class ConfigTrans {
public void addJob()
{
//数据库操作
}
}
上面这段代码中,可以不用关心事务处理的问题,在需要使用事务的时候,可以通过下面的上下文配置声明式事务处理。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<!-- 数据源配置开始 -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.microsoft.jdbc.sqlserver.SQLServerDriver</value>
</property>
<property name="url">
<value>jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=pubs
</value>
</property>
<property name="username">
<value>sa</value>
</property>
<property name="password">
<value>1985315</value>
</property>
</bean>
<!-- 数据源配置结束 -->
<!-- transManager事务管理器配置开始,配置的dataSourceTransctionManager可作为jdbc和mybatis等的管理器 -->
<bean id="transManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
<!-- transManager事务管理器配置结束 -->
<!-- 配置事务的传播特性和隔离级别 -->
<bean id="transAttributeSource"
class="org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource">
<property name="properties">
<props>
<prop key="addJob">
PROPAGATION_REQUIRED,ISOLATION_DEFAULT
</prop>
</props>
</property>
</bean>
<!-- 事务管理的策略配置结束 -->
<!-- 事务管理的目标Bean配置开始 -->
<bean id="configTransTarget" class="trans.config.ConfigTrans"></bean>
<!-- 事务管理的目标Bean配置结束 -->
<!-- 事务管理代理Bean配置开始 -->
<bean id="configTrans"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="target">
<ref bean="configTransTarget" />
</property>
<property name="transactionManager">
<ref bean="transManager" />
</property>
<property name="transactionAttributeSource">
<ref bean="transAttributeSource" />
</property>
</bean>
<!-- 事务管理代理Bean配置结束 -->
</beans>
在上面这个上下文配置文件中,configTans这个bean配置了一个TransactionProxyFactoryBean,通过这个bean可以给目标对象添加事务处理功能;configTansTarget这个bean就是要实现事务管理的目标对象;transactionManager定义了一个DataSourceTransactionManager类型的事务管理器;transactionAttributeSource定义的是事务管理的策略。
通过上面这样的配置,在使用事务处理的时候,调用经过事务管理以后的bean对象即可,Spring会通过AOP框架,自动给目标对象添加事务处理的功能。