Spring进行编程式事务管理和声明式事务管理

  • Spring事务管理

 

  • PlatformTransaction接口

voidcommit(TransactionStatus status)

Commit the given transaction, with regard to its status.

TransactionStatusgetTransaction(TransactionDefinition definition)

Return a currently active transaction or create a new one, according to the specified propagation behavior.

voidrollback(TransactionStatus status)

Perform a rollback of the given transaction.

  • TransactionDefinetion接口(定义事务的隔离级别,传播行为)

static intISOLATION_DEFAULT

Use the default isolation level of the underlying datastore.

static intISOLATION_READ_COMMITTED

Indicates that dirty reads are prevented; non-repeatable reads and phantom reads can occur.

static intISOLATION_READ_UNCOMMITTED

Indicates that dirty reads, non-repeatable reads and phantom reads can occur.

static intISOLATION_REPEATABLE_READ

Indicates that dirty reads and non-repeatable reads are prevented; phantom reads can occur.

static intISOLATION_SERIALIZABLE

Indicates that dirty reads, non-repeatable reads and phantom reads are prevented.

static intPROPAGATION_MANDATORY

Support a current transaction; throw an exception if no current transaction exists.

static intPROPAGATION_NESTED

Execute within a nested transaction if a current transaction exists, behave like PROPAGATION_REQUIRED else.

static intPROPAGATION_NEVER

Do not support a current transaction; throw an exception if a current transaction exists.

static intPROPAGATION_NOT_SUPPORTED

Do not support a current transaction; rather always execute non-transactionally.

static intPROPAGATION_REQUIRED

Support a current transaction; create a new one if none exists.

static intPROPAGATION_REQUIRES_NEW

Create a new transaction, suspending the current transaction if one exists.

static intPROPAGATION_SUPPORTS

Support a current transaction; execute non-transactionally if none exists.

static intTIMEOUT_DEFAULT

Use the default timeout of the underlying transaction system, or none if timeouts are not supported.

  • 事务的隔离级别

  • 事务的传播行为

PROPAGATION用来定义事务的传播行为,用来解决业务层方法的相互调用所产生的事务应该如何传递的问题。 事务控制加在业务层,那么怎么在业务层控制事务呢? 

  • TransactionStatus接口

voidflush()

Flush the underlying session to the datastore, if applicable: for example, all affected Hibernate/JPA sessions.

booleanhasSavepoint()  //事务是否有保存点

Return whether this transaction internally carries a savepoint, that is, has been created as nested transaction based on a savepoint.

booleanisCompleted()

Return whether this transaction is completed, that is, whether it has already been committed or rolled back.

booleanisNewTransaction()

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).

booleanisRollbackOnly()

Return whether the transaction has been marked as rollback-only (either by the application or by the transaction infrastructure).

voidsetRollbackOnly()

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&amp;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 {};

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值