-
Spring事务管理
-
PlatformTransaction接口
void | commit(TransactionStatus status) Commit the given transaction, with regard to its status. |
TransactionStatus | getTransaction(TransactionDefinition definition) Return a currently active transaction or create a new one, according to the specified propagation behavior. |
void | rollback(TransactionStatus status) Perform a rollback of the given transaction. |
-
TransactionDefinetion接口(定义事务的隔离级别,传播行为)
static int | ISOLATION_DEFAULT Use the default isolation level of the underlying datastore. |
static int | ISOLATION_READ_COMMITTED Indicates that dirty reads are prevented; non-repeatable reads and phantom reads can occur. |
static int | ISOLATION_READ_UNCOMMITTED Indicates that dirty reads, non-repeatable reads and phantom reads can occur. |
static int | ISOLATION_REPEATABLE_READ Indicates that dirty reads and non-repeatable reads are prevented; phantom reads can occur. |
static int | ISOLATION_SERIALIZABLE Indicates that dirty reads, non-repeatable reads and phantom reads are prevented. |
static int | PROPAGATION_MANDATORY Support a current transaction; throw an exception if no current transaction exists. |
static int | PROPAGATION_NESTED Execute within a nested transaction if a current transaction exists, behave like |
static int | PROPAGATION_NEVER Do not support a current transaction; throw an exception if a current transaction exists. |
static int | PROPAGATION_NOT_SUPPORTED Do not support a current transaction; rather always execute non-transactionally. |
static int | PROPAGATION_REQUIRED Support a current transaction; create a new one if none exists. |
static int | PROPAGATION_REQUIRES_NEW Create a new transaction, suspending the current transaction if one exists. |
static int | PROPAGATION_SUPPORTS Support a current transaction; execute non-transactionally if none exists. |
static int | TIMEOUT_DEFAULT Use the default timeout of the underlying transaction system, or none if timeouts are not supported. |
-
事务的隔离级别
-
事务的传播行为
PROPAGATION用来定义事务的传播行为,用来解决业务层方法的相互调用所产生的事务应该如何传递的问题。 事务控制加在业务层,那么怎么在业务层控制事务呢?
-
TransactionStatus接口
void | flush() Flush the underlying session to the datastore, if applicable: for example, all affected Hibernate/JPA sessions. |
boolean | hasSavepoint() //事务是否有保存点 Return whether this transaction internally carries a savepoint, that is, has been created as nested transaction based on a savepoint. |
boolean | isCompleted() Return whether this transaction is completed, that is, whether it has already been committed or rolled back. |
boolean | isNewTransaction() Return whether the present transaction is new (else participating in an existing transaction, or potentially not running in an actual transaction in the first place). |
boolean | isRollbackOnly() Return whether the transaction has been marked as rollback-only (either by the application or by the transaction infrastructure). |
void | setRollbackOnly() Set the transaction rollback-only. |
平台事务管理器通过事务的隔离级别和传播行为来进行事务的管理,在这期间,需要判断事务的状态,如可能已经产生了保存点,或事务是一个新的事务。
Spring支持两种方式事务管理。这里重点需要掌握声明式事务管理,因为不需要编写代码来进行事务的管理。声明式的事务管理通过AOP来时,进行代码增强。代码执行前开启事务,代码执行末尾提交事务。需要一个事务管理环境进行开发,所以需要搭建事务管理环境。创建数据库和表,如账户表(id,name,money),分别向表中插入数据。并初始化金额。
创建数据库,和数据表。
create database spring_transaction;
use spring_transaction;
CREATE TABLE `account` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
`money` double DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
INSERT INTO `account` VALUES ('1', 'aaa', '1000');
INSERT INTO `account` VALUES ('2', 'bbb', '1000');
INSERT INTO `account` VALUES ('3', 'ccc', '1000');
mysql> show tables;
+------------------------------+
| Tables_in_spring_transaction |
+------------------------------+
| account |
+------------------------------+
1 row in set (0.00 sec)
mysql> select * from account;
+----+------+-------+
| id | name | money |
+----+------+-------+
| 1 | aaa | 1000 |
| 2 | bbb | 1000 |
| 3 | ccc | 1000 |
+----+------+-------+
数据库创建好了之后,接下来创建项目,引入jar包和配置文件。
-
编程式事务管理编码实现
applicationContext.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"
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">
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="accountDao" class="com.imooc.spr_trans.dao.AccountDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="accountService" class="com.imooc.spr_trans.service.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
<property name="transactionTemplate" ref="transactionTemplate"/>
</bean>
<!--配置 编程式的事务管理 事务管理器,业务层的类需要进行事务管理,即在业务层注入事务管理的模版-->
<bean id="dsTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--配置spring为方便事务的管理而提供的事务管理器的模版-->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="dsTransactionManager"/>
</bean>
</beans>
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.username=root
jdbc.password=123456
jdbc.url=jdbc:mysql://localhost:3306/spring_transaction?useUnicode=true&characterEncoding=utf-8
log4j.properties
### 设置###
log4j.rootLogger = debug,stdout,D,E
### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
### 输出DEBUG 级别以上的日志到=logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
### 输出ERROR 级别以上的日志到=logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File = logs/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
AccountDao
package com.imooc.spr_trans.dao;
public interface AccountDao {
void outMoney(String out, Double money);
void inMoney(String in,Double money);
}
AccountDaoImpl
package com.imooc.spr_trans.dao;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{
public void outMoney(String out, Double money) {
String sql = "update account set money = money - ? where name = ?";
this.getJdbcTemplate().update(sql,money,out);
}
public void inMoney(String in, Double money) {
String sql = "update account set money = money + ? where name = ?";
this.getJdbcTemplate().update(sql,money,in);
}
}
AccountService
package com.imooc.spr_trans.service;
public interface AccountService {
void transter(String out,String in,Double money);
}
AccountServiceImpl(这里进行编程式事务管理)
为了方便对事务进行管理,spring提供了TransactionTemplate来方便对事务进行管理。(这和JdbcTemplate方便对数据库操作如出一辙)
package com.imooc.spr_trans.service;
import com.imooc.spr_trans.dao.AccountDao;
import com.imooc.spr_trans.dao.AccountDaoImpl;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
public class AccountServiceImpl implements AccountService{
//因为在xml中,AccountDao作为一个属性,被注入进了AccountService,所以这个直接使用setter函数给私有成员变量设置值
private AccountDao accountDao;
private TransactionTemplate transactionTemplate;
public void setAccountDao(AccountDaoImpl accountDao) {
this.accountDao = accountDao;
}
public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
this.transactionTemplate = transactionTemplate;
}
public void transter(String out, String in, Double money) {
transactionTemplate.execute(new MyT(out,in,money));
}
private class MyT extends TransactionCallbackWithoutResult{
private String out;
private String in;
private Double money;
MyT(String out,String in,Double money){
this.out = out;
this.in = in;
this.money = money;
}
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
accountDao.inMoney(in,money);
int i = 1 / 0;//专门用来产生异常信息,则事务会回滚
accountDao.outMoney(out,money);
}
}
}
测试
package com.imooc.spr_trans;
import com.imooc.spr_trans.service.AccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringDemo {
@Autowired
private AccountService accountService;
@Test
public void demo01(){
accountService.transter("aaa","bbb",5.0);
}
}
可见,进行编程式的事务管理,需要程序员手动更改service的代码,这种方式不好,对于开发来说不经常用。不如声明式的事务管理,基于AOP思想。
-
声明式事务管理
-
方法一:基于TransactionProxyFactoryBean
AccountDao
package com.imooc.spring.demo2.dao;
public interface AccountDao {
void outMoney(String out, Double money);
void inMoney(String in, Double money);
}
AccountDaoImpl
package com.imooc.spring.demo2.dao;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
public void outMoney(String out, Double money) {
String sql = "update account set money = money - ? where name = ?";
this.getJdbcTemplate().update(sql,money,out);
}
public void inMoney(String in, Double money) {
String sql = "update account set money = money + ? where name = ?";
this.getJdbcTemplate().update(sql,money,in);
}
}
AccountService
package com.imooc.spring.demo2.service;
public interface AccountService {
void transter(String out, String in, Double money);
}
AccountServiceImpl
package com.imooc.spring.demo2.service;
import com.imooc.spring.demo2.dao.AccountDao;
import com.imooc.spring.demo2.dao.AccountDaoImpl;
public class AccountServiceImpl implements AccountService {
//因为在xml中,AccountDao作为一个属性,被注入进了AccountService,所以这个直接使用setter函数给私有成员变量设置值
private AccountDao accountDao;
public void setAccountDao(AccountDaoImpl accountDao) {
this.accountDao = accountDao;
}
public void transter(String out, String in, Double money) {
accountDao.outMoney(out,money);
//int i = 1 / 0;
accountDao.inMoney(in,money);
}
}
测试
applicationContext.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:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="accountDao" class="com.imooc.spring.demo2.dao.AccountDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="accountService" class="com.imooc.spring.demo2.service.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
</bean>
<!--配置事务管理器-->
<bean id="dsTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--配置业务层的代理-->
<bean id="accountServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="dsTransactionManager"/>
<property name="target" ref="accountService"/>
<property name="transactionAttributes">
<props>
<!--
* PROPAGATION :事务的传播行为
* ISOLATION : 事务的隔离级别
* readOnly : 只读(不可以进行修改,产出,插入等操作)
* -Exception :发生哪些异常回滚事务
* +Exception :发生哪些异常事务不回滚
配置好了之后,业务层代码不需要发生任何变化,因为是基于AOP思想
-->
<prop key="transter">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
</beans>
定义事务的隔离级别,事务的传播行为。
-
方法二:基于AspectJ的XML方式
基于TransactionProxyFactoryBean的方式进行事务管理,商品,订单,等都需要定义,配置文件中需要配置很多的TransactionProxyFactoryBean,不方便。使用基于AspectJ的方式进行事务管理更加方便。
AspectJ是开源第三方的AOP开发框架,其可以简化Spring进行AOP开发。
因为是基于XML方式实现的,所以不需要更改源代码。但是需要修改applicationContext.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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="accountDao" class="com.imooc.spring.demo3.dao.AccountDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="accountService" class="com.imooc.spring.demo3.service.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
</bean>
<!--配置事务管理器-->
<bean id="dsTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--配置事务的通知(事务的增强)基于AspectJ的事务管理-->
<tx:advice id="txAdvice" transaction-manager="dsTransactionManager">
<tx:attributes>
<tx:method name="transfer" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!--配置切面-->
<aop:config>
<aop:pointcut expression="execution(* com.imooc.spring.demo3.service.AccountService+.*(..))" id="pointcut1"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/>
</aop:config>
</beans>
测试
package com.imooc.spring.demo3;
import com.imooc.spring.demo3.service.AccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
/*
声明式的事务管理,方法一:传统方式
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext3.xml")
public class SpringDemo {
//基于BeanPostProfessor,在注入类的过程中就已经对类进行了增强,本身就是一个代理对象,所以可以直接注入。
@Resource(name = "accountService")
private AccountService accountService;
@Test
public void demo01(){
accountService.transfer("aaa","bbb",200d);
}
}
-
方法三:使用注解配置声明式事务(在业务层添加Transactional注解,在xml中打开事务注解驱动)
applicationContext.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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="accountDao" class="com.imooc.spring.demo4.dao.AccountDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="accountService" class="com.imooc.spring.demo4.service.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
</bean>
<!--配置事务管理器-->
<bean id="dsTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--开启注解事务-->
<tx:annotation-driven transaction-manager="dsTransactionManager" />
</beans>
测试
package com.imooc.spring.demo4;
import com.imooc.spring.demo4.service.AccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
/*
声明式的事务管理,方法一:传统方式
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext4.xml")
public class SpringDemo {
//基于BeanPostProfessor,在注入类的过程中就已经对类进行了增强,本身就是一个代理对象,所以可以直接注入。
@Resource(name = "accountService")
private AccountService accountService;
@Test
public void demo01(){
accountService.transfer("aaa","bbb",200d);
}
}
附 Transactional
/*
* Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.transaction.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.transaction.TransactionDefinition;
/**
* Describes transaction attributes on a method or class.
*
* <p>This annotation type is generally directly comparable to Spring's
* {@link org.springframework.transaction.interceptor.RuleBasedTransactionAttribute}
* class, and in fact {@link AnnotationTransactionAttributeSource} will directly
* convert the data to the latter class, so that Spring's transaction support code
* does not have to know about annotations. If no rules are relevant to the exception,
* it will be treated like
* {@link org.springframework.transaction.interceptor.DefaultTransactionAttribute}
* (rolling back on runtime exceptions).
*
* <p>For specific information about the semantics of this annotation's attributes,
* consider the {@link org.springframework.transaction.TransactionDefinition} and
* {@link org.springframework.transaction.interceptor.TransactionAttribute} javadocs.
*
* @author Colin Sampaleanu
* @author Juergen Hoeller
* @since 1.2
* @see org.springframework.transaction.interceptor.TransactionAttribute
* @see org.springframework.transaction.interceptor.DefaultTransactionAttribute
* @see org.springframework.transaction.interceptor.RuleBasedTransactionAttribute
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
/**
* A qualifier value for the specified transaction.
* <p>May be used to determine the target transaction manager,
* matching the qualifier value (or the bean name) of a specific
* {@link org.springframework.transaction.PlatformTransactionManager}
* bean definition.
*/
String value() default "";
/**
* The transaction propagation type.
* Defaults to {@link Propagation#REQUIRED}.
* @see org.springframework.transaction.interceptor.TransactionAttribute#getPropagationBehavior()
*/
Propagation propagation() default Propagation.REQUIRED;
/**
* The transaction isolation level.
* Defaults to {@link Isolation#DEFAULT}.
* @see org.springframework.transaction.interceptor.TransactionAttribute#getIsolationLevel()
*/
Isolation isolation() default Isolation.DEFAULT;
/**
* The timeout for this transaction.
* Defaults to the default timeout of the underlying transaction system.
* @see org.springframework.transaction.interceptor.TransactionAttribute#getTimeout()
*/
int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
/**
* <code>true</code> if the transaction is read-only.
* Defaults to <code>false</code>.
* <p>This just serves as a hint for the actual transaction subsystem;
* it will <i>not necessarily</i> cause failure of write access attempts.
* A transaction manager which cannot interpret the read-only hint will
* <i>not</i> throw an exception when asked for a read-only transaction.
* @see org.springframework.transaction.interceptor.TransactionAttribute#isReadOnly()
*/
boolean readOnly() default false;
/**
* Defines zero (0) or more exception {@link Class classes}, which must be a
* subclass of {@link Throwable}, indicating which exception types must cause
* a transaction rollback.
* <p>This is the preferred way to construct a rollback rule, matching the
* exception class and subclasses.
* <p>Similar to {@link org.springframework.transaction.interceptor.RollbackRuleAttribute#RollbackRuleAttribute(Class clazz)}
*/
Class<? extends Throwable>[] rollbackFor() default {};
/**
* Defines zero (0) or more exception names (for exceptions which must be a
* subclass of {@link Throwable}), indicating which exception types must cause
* a transaction rollback.
* <p>This can be a substring, with no wildcard support at present.
* A value of "ServletException" would match
* {@link javax.servlet.ServletException} and subclasses, for example.
* <p><b>NB: </b>Consider carefully how specific the pattern is, and whether
* to include package information (which isn't mandatory). For example,
* "Exception" will match nearly anything, and will probably hide other rules.
* "java.lang.Exception" would be correct if "Exception" was meant to define
* a rule for all checked exceptions. With more unusual {@link Exception}
* names such as "BaseBusinessException" there is no need to use a FQN.
* <p>Similar to {@link org.springframework.transaction.interceptor.RollbackRuleAttribute#RollbackRuleAttribute(String exceptionName)}
*/
String[] rollbackForClassName() default {};
/**
* Defines zero (0) or more exception {@link Class Classes}, which must be a
* subclass of {@link Throwable}, indicating which exception types must <b>not</b>
* cause a transaction rollback.
* <p>This is the preferred way to construct a rollback rule, matching the
* exception class and subclasses.
* <p>Similar to {@link org.springframework.transaction.interceptor.NoRollbackRuleAttribute#NoRollbackRuleAttribute(Class clazz)}
*/
Class<? extends Throwable>[] noRollbackFor() default {};
/**
* Defines zero (0) or more exception names (for exceptions which must be a
* subclass of {@link Throwable}) indicating which exception types must <b>not</b>
* cause a transaction rollback.
* <p>See the description of {@link #rollbackForClassName()} for more info on how
* the specified names are treated.
* <p>Similar to {@link org.springframework.transaction.interceptor.NoRollbackRuleAttribute#NoRollbackRuleAttribute(String exceptionName)}
*/
String[] noRollbackForClassName() default {};
}