1、10.1传统使用JDBC的事务管理Connection conn=null;Statement statement=null;try Class.forName(org.gjt.mm.mysql.Driver);/假设连接假设连接mysql数据库数据库 conn=DriverManager.getConnection(jdbc:mysql:/127.0.0.1/data,root,123);statement=conn.createStatement();conn.setAutoCommit(false);/具体数据访问操作略具体数据访问操作略 mit();catch(SQLException
2、 se)conn.rollback();10.2 Spring提供的编程式事务处理(1)TransactionDefinition:定义事务属性的接口。:定义事务属性的接口。其中定义了一系列方法可分别获取事务的名称、传播其中定义了一系列方法可分别获取事务的名称、传播行为、隔离层次、超时等属性。具体方法有:行为、隔离层次、超时等属性。具体方法有:int getIsolationLevel():获取事务隔离级别。:获取事务隔离级别。int getPropagationBehavior():获取事务传播策:获取事务传播策略。略。int getTimeout():获取事务超时时间。:获取事务超时时间。
3、boolean isReadOnly():获取事务的只读属性。:获取事务的只读属性。String getName():返回事务的名称。:返回事务的名称。(2)TransactionStatus:定义事务管理状态:定义事务管理状态的接口。其主要方法有:的接口。其主要方法有:boolean isNewTransaction():返回当前事:返回当前事务是不是新创建的。务是不是新创建的。void setRollbackOnly():设置事务执行回:设置事务执行回滚操作。滚操作。boolean isRollbackOnly():返回当前事务:返回当前事务是否已被标记为回滚。是否已被标记为回滚。bool
4、ean isCompleted():返回该事务是否:返回该事务是否已经完成(提交或回滚)。已经完成(提交或回滚)。(3)PlatformTransactionManager:用于管理事务的基础接口,随着底层不同事务策略有不同的实现类。例如:用于管理事务的基础接口,随着底层不同事务策略有不同的实现类。例如:DataSourceTransactionManager用于使用用于使用JDBC或或iBatis进行数据持进行数据持久化操作的情况;久化操作的情况;HibernateTransactionManager用于使用用于使用Hibernate进行数据持久化操作的情况;进行数据持久化操作的情况;Jpa
5、TransactionManager用用于使用于使用JPA进行数据持久化操作的情况。进行数据持久化操作的情况。PlatformTransactionManager的常用方法有:的常用方法有:TransactionStatus getTransaction(TransactionDefinition definition):返回所定义事务的状态。:返回所定义事务的状态。void commit(TransactionStatus status):根据事务状态,提交指定:根据事务状态,提交指定的事务。的事务。void rollback(TransactionStatus status):对指定事务执
6、行回滚操:对指定事务执行回滚操作。作。10.2.1 使用TransactionTemplate进行事务处理 Spring的的TransactionTemplate在编程中可省去事在编程中可省去事务提交、回滚代码。但要将数据库的操作代码安排在务提交、回滚代码。但要将数据库的操作代码安排在Spring的事务模板的处理框架内,的事务模板的处理框架内,Spring 将自动进将自动进行行 commit 和和 rollback处理。处理。TransactionTemplate是采用回调机制实现方法调用,是采用回调机制实现方法调用,Spring 为为TransactionTemplate 准备了两个回调接准
7、备了两个回调接口口:TransactionCallback和和TransactionCallbackWithoutResult。它们分别用。它们分别用于有返回结果和无返回结果两种操作情形。实际上是于有返回结果和无返回结果两种操作情形。实际上是分别回调执行接口中定义的分别回调执行接口中定义的doInTransaction和和doInTransactionWithoutResult方法。方法。TransactionTemplate transactionTemplate=new TransactionTemplate(transactionManager);/以下调用以下调用 transactio
8、nTemplate 的的 execute 方法进行事务管理方法进行事务管理 transactionTemplate.execute(new TransactionCallbackWithoutResult()public void doInTransactionWithoutResult(TransactionStatus status)for(int k=0;kusernames.length;k+)/循环注册一批循环注册一批帐户帐户 register(prefix+k,111111,usernamesk);/注册注册一个账户一个账户 );10.2.2 程序根据JdbcTemplate处理结
9、果进行提交和回滚DefaultTransactionDefinition def=new DefaultTransactionDefinition();TransactionStatus status=transactionManager.getTransaction(def);try JdbcTemplate jdbcTemplate=new JdbcTemplate(dataSource);for(int k=0;kusernames.length;k+)String sql=insert into user values(+prefix+k+,+111111,+usernamesk+,1
10、0);jdbcTemplate.execute(sql);transactionMmit(status);/事务提交事务提交 catch(DataAccessException ex)/出现数据访问异常出现数据访问异常 transactionManager.rollback(status);/事务回滚事务回滚 10.3 Spring声明式事务处理Spring声明式事务处理使用了声明式事务处理使用了IOC和和AOP的思想,因此,需要将的思想,因此,需要将aopalliance.jar和和cglib-nodep-2.1_3.jar加入到类路径中。加入到类路径中。Spring提供了提供了Transa
11、ctionInterceptor拦截拦截器和常用的代理类器和常用的代理类TransactionProxyFactoryBean,可以直接,可以直接对组件进行事务代理。在配置文件中通过属性对组件进行事务代理。在配置文件中通过属性设置声明应用中的哪些操作需要进行事务处理设置声明应用中的哪些操作需要进行事务处理即可。即可。10.3.1 用TransactionInterceptor拦截器进行事务管理 chapter10.UserDao.insertUsers*=PROPAGATION_REQUIRED 相应的相应的insertUsers代码中不用含任何事务代码。代码中不用含任何事务代码。propag
12、ation属性事务属性中,事务属性中,propagation属性代表事务的传播方式,它有如下取值。属性代表事务的传播方式,它有如下取值。PROPAGATION_REQUIRED:业务方法需要在一个事务中运行:业务方法需要在一个事务中运行,如果方法运行如果方法运行时时,已处在一个事务中已处在一个事务中,则直接调用则直接调用,否则创建一个新事务后执行该方法。这是否则创建一个新事务后执行该方法。这是spring默认的传播行为。默认的传播行为。PROPAGATION_SUPPORTS:如果业务方法在某个事务范围内被调用:如果业务方法在某个事务范围内被调用,则方法则方法成为该事务的一部分成为该事务的一部
13、分,如果业务方法在事务范围外被调用如果业务方法在事务范围外被调用,则方法在没有事务的环则方法在没有事务的环境下执行。境下执行。PROPAGATION_MANDATORY:只能在一个已存在事务中执行:只能在一个已存在事务中执行,业务方法不能业务方法不能发起自己的事务发起自己的事务,如果业务方法在没有事务的环境下调用如果业务方法在没有事务的环境下调用,就抛异常。就抛异常。PROPAGATION_REQUIRES_NEW:业务方法要求在新的事务环境中,如果:业务方法要求在新的事务环境中,如果方法已运行在一个事务中方法已运行在一个事务中,则原有事务被挂起则原有事务被挂起,新的事务被创建新的事务被创建,
14、直到方法结束直到方法结束,原先原先的事务才会恢复执行。的事务才会恢复执行。PROPAGATION_NOT_SUPPORTED:如果方法在一个事务中被调用:如果方法在一个事务中被调用,该事务该事务会被挂起会被挂起,在方法调用结束后在方法调用结束后,原先的事务便会恢复执行。原先的事务便会恢复执行。PROPAGATION_NEVER:声明方法绝对不能在事务范围内执行,否则将抛出:声明方法绝对不能在事务范围内执行,否则将抛出异常。异常。PROPAGATION_NESTED:如果一个活动的事务存在:如果一个活动的事务存在,则运行在一个嵌套的事务则运行在一个嵌套的事务中。如果没有活动的事务中。如果没有活动
15、的事务,则按则按REQUIRED属性执行。属性执行。10.3.2 用TransactionProxyFactoryBean进行事务管理 PROPAGATION_REQUIREDPROPAGATION_REQUIRED 10.4 使用Transactional注解Transactional注解提供了一系列属性修饰,以给出事务处理的明确信息。注解提供了一系列属性修饰,以给出事务处理的明确信息。isolation:事务隔离级别,默认为:事务隔离级别,默认为Default,表示底层事务的隔离级别;表示底层事务的隔离级别;propagation:事务传播属性:事务传播属性,默认值为,默认值为REQUIR
16、ED;readOnly:是否事务是否只读:是否事务是否只读;timeout:指定事务超时:指定事务超时(秒秒)时间;时间;rollbackFor:指定遇到指定异常需要回滚事务;:指定遇到指定异常需要回滚事务;rollbackForClassName:指定遇到指定异常类名需要回滚事务,该属:指定遇到指定异常类名需要回滚事务,该属性可指定多个异常类名;性可指定多个异常类名;noRollbackFor:指定遇到指定异常不需要回滚事务;:指定遇到指定异常不需要回滚事务;noRollbackForClassName:指定遇到指定异常类名不需要回滚事务。:指定遇到指定异常类名不需要回滚事务。【程序清单10
17、-6】文件名为UserDaoImpl.javapackage chapter10;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;public class UserDaoImpl implements UserDao Transactional(propagation=Propagation.REQUIRED)public void insertUsers(String prefix,Stri
18、ng usernames)for(int k=0;kusernames.length;k+)register(prefix+k,111111,usenamesk,10);10.4.1 相关的XML配置 10.4.2 使用Transactional注解几点注意(1)Transactional注解只能被应用到注解只能被应用到public方法上方法上,对于其它非对于其它非public的方法的方法,如如果标记了果标记了Transactional也不会报错也不会报错,但方法没有事务功能但方法没有事务功能.(2)默认情况下默认情况下,一个有事务的方法一个有事务的方法,遇到遇到RuntiomeExcepti
19、on 时会回滚,遇到受检时会回滚,遇到受检查的异常是不会回滚的。要想所有异常都回滚查的异常是不会回滚的。要想所有异常都回滚,要加上要加上rollbackFor属性。属性。例如,以下代码指定回滚例如,以下代码指定回滚,遇到异常遇到异常Exception时回滚。时回滚。Transactional(rollbackFor=Exception.class)public void methodName()throw new Exception(注释注释);(3)声明式事务配置后,所有)声明式事务配置后,所有Bean将建立事务代理。所以编程时从系统环境获取将建立事务代理。所以编程时从系统环境获取Bean不能指明实现接口的类。而是直接通过不能指明实现接口的类。而是直接通过Bean标识获取标识获取Bean,再强制转换为相,再强制转换为相应接口类型,通过接口进行对象访问处理。应接口类型,通过接口进行对象访问处理。