在数据库操作中,事务处理十分重要,在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框架,自动给目标对象添加事务处理的功能。