深入解读Spring Framework事务管理(第四弹:基于@Transactional注解的声明式事务管理)
2016-12-31 19:55
519 查看
基于注解的声明式事务,主要使用的是@Transactional注解,下面我们来具体看一下。
当我们在Spring IoC容器中定义上面这个POJO时,我们只需要在XML配置里添加一行就可以使这个bean的实例事务化。
当使用代理时,@Transactional注解要加在public的方法上。如果给protected、private或者包访问的方法添加@Transactional注解,不会产生错误,但是事务并不会生效。如果要给非public的方法添加注解可以参考AspectJ。
尽管我们可以把@Transactional注解加在接口定义、接口中的方法定义、类定义或者类中的public方法定义的前面,不过Spring建议我们在类或者类的方法上加注解,而不要在接口上加注解。然而光有@Transactional注解还是不够让事务生效的,@Transactional注解仅仅是一个元数据,要使用这个元数据,还需要
@EnableTransactionManagement和
在决定方法的事务设置时,会取最精确的配置,比如:
传播行为是PROPAGATION_REQUIRED
隔离级别是ISOLATION_DEFAULT
事务是可读可写的
事务超时是使用系统底层组件的默认值,不支持超时的时候就没有超时设置
任何的RuntimeException都会触发回滚,checked Exception不会。
@Transactional注解的各种属性如下:
可以和下面的事务管理器的bean绑定:
这样,TransactionalService中的两个方法将会分别运行在独立的事务管理器中,通过”order”和”account”的修饰符区分。
然后我们就能这么用:
使用@Transactional注解实现事务的例子
// 这个service我们要将他事务化 @Transactional public class DefaultFooService implements FooService { Foo getFoo(String fooName); Foo getFoo(String fooName, String barName); void insertFoo(Foo foo); void updateFoo(Foo foo); }
当我们在Spring IoC容器中定义上面这个POJO时,我们只需要在XML配置里添加一行就可以使这个bean的实例事务化。
<!-- from the file 'context.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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.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"> <!-- 这个service对象我们要让他支持事务 --> <bean id="fooService" class="x.y.service.DefaultFooService"/> <!-- 基于注解的事务配置 --> <tx:annotation-driven transaction-manager="txManager"/> <!-- 事务管理器(PlatformTransactionManager)仍然是需要的 --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 配置数据源 --> <!-- 其他的bean定义 --> </beans>
<tx:annotation-driven/>标签里的transaction-manager属性值是PlatformTransactionManager对象的bean的名字,如果不写的话默认就叫“transactionManager”。我们这个例子里没有用默认,指定的是叫“txManager”。
当使用代理时,@Transactional注解要加在public的方法上。如果给protected、private或者包访问的方法添加@Transactional注解,不会产生错误,但是事务并不会生效。如果要给非public的方法添加注解可以参考AspectJ。
尽管我们可以把@Transactional注解加在接口定义、接口中的方法定义、类定义或者类中的public方法定义的前面,不过Spring建议我们在类或者类的方法上加注解,而不要在接口上加注解。然而光有@Transactional注解还是不够让事务生效的,@Transactional注解仅仅是一个元数据,要使用这个元数据,还需要
<tx:annotation-driven/>来配置bean的事务行为。
<tx:annotation-driven/>的设置
XML Attribute | Annotation Attribute | Default | Description |
---|---|---|---|
transaction-manager | N/A | transactionManager | 要使用的事务管理器的名字。只有在事务管理器的名字不是transactionManager的时候才是必须的 |
mode | mode | proxy | 默认值“proxy”使得注解了的bean使用Spring的AOP框架来代理。候选的“aspectj”模式使用了Spring的AspectJ transaction aspect对目标类进行编织,通过修改目标类的字节码来让任何的方法调用都能产生事务 |
proxy-target-class | proxyTargetClass | false | 只在代理模式生效。控制使用@Transactional注解的类将会创建什么类型的事务代理。如果proxy-target-class的属性值设为true,那就创建基于类的代理,如果设为false,那就会创建标准JDK的基于接口的代理。 |
order | order | Ordered.LOWEST_PRECEDENCE | 定义添加了@Transactional注解的bean上的事务通知的顺序。不指定顺序意味着有AOP底层系统决定通知的顺序 |
<tx:annotation-driven/>只会查找在同一个应用上下文中定义的bean的@Transactional注解。也就是说,如果在一个DispatcherServlet的WebApplicationContext中添加了注解驱动的配置,那么只会在controllers中查找@Transactional beans,而不是在services里查找。
在决定方法的事务设置时,会取最精确的配置,比如:
@Transactional(readOnly = true) public class DefaultFooService implements FooService { public Foo getFoo(String fooName) { // do something } // 这里的事务设置更优先 @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) public void updateFoo(Foo foo) { // do something } }
@Transactional的设置
@Transactional注解是一个用来定义一个接口、类或者方法的事务化语义的元数据。@Transactional注解的默认设置如下:传播行为是PROPAGATION_REQUIRED
隔离级别是ISOLATION_DEFAULT
事务是可读可写的
事务超时是使用系统底层组件的默认值,不支持超时的时候就没有超时设置
任何的RuntimeException都会触发回滚,checked Exception不会。
@Transactional注解的各种属性如下:
Property | Type | Description |
---|---|---|
value | String | 指定事务管理器使用的可选限定符 |
propagation | enum: Propagation | 指定传播行为 |
isolation | enum: Isolation | 指定隔离级别 |
readOnly | boolean | 设置事务是可读可写还是只读 |
timeout | int (以秒为单位) | 事务超时 |
rollbackFor | Class对象数组,必须是继承自Throwable的 | 指定会触发回滚的异常类的数组 |
rollbackForClassName | 类名的数组,类必须是继承自Throwable的 | 指定会触发回滚的异常类名的数组 |
noRollbackFor | Class对象数组,必须是继承自Throwable的 | 指定不会触发回滚的异常类的数组 |
noRollbackForClassName | 类名的数组,类必须是继承自Throwable的 | 指定不会触发回滚的异常类名的数组 |
@Transactional使用多个事务管理器
一般来讲我们只需要使用一个事务管理器,不过也存在需要多个的情况。@Transactional的value属性可以指定要使用的不同的PlatformTransactionManager。这可以是bean的名称或者事务管理器bean的修饰值。比如下面的代码:public class TransactionalService { @Transactional("order") public void setSomething(String name) { ... } @Transactional("account") public void doSomething() { ... } }
可以和下面的事务管理器的bean绑定:
<tx:annotation-driven/> <bean id="transactionManager1" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> ... <qualifier value="order"/> </bean> <bean id="transactionManager2" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> ... <qualifier value="account"/> </bean>
这样,TransactionalService中的两个方法将会分别运行在独立的事务管理器中,通过”order”和”account”的修饰符区分。
<tx:annotation-driven/>的默认目标bean名称transactionManager会在指定的修饰符没有找到时使用。
自定义快捷注解
先自定义快捷注解,例如:@Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Transactional("order") public @interface OrderTx { } @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Transactional("account") public @interface AccountTx { }
然后我们就能这么用:
public class TransactionalService { @OrderTx public void setSomething(String name) { ... } @AccountTx public void doSomething() { ... } }
相关文章推荐
- 深入解读Spring Framework事务管理(第三弹:基于AspectJ的XML声明式事务管理)
- 基于@Transactional注解方式的spring声明式事务管理
- spring事物配置,声明式事务管理和基于@Transactional注解的使用
- spring事物配置,声明式事务管理和基于@Transactional注解的使用
- spring事物配置,声明式事务管理和基于@Transactional注解的使用
- spring事物配置,声明式事务管理和基于@Transactional注解的使用
- spring事物配置,声明式事务管理和基于@Transactional注解的使用
- spring事物配置,声明式事务管理和基于@Transactional注解的使用 [转]
- spring事物配置,声明式事务管理和基于@Transactional注解的使用
- spring事物配置,声明式事务管理和基于@Transactional注解的使用
- spring事物配置,声明式事务管理和基于@Transactional注解的使用
- spring事物配置,声明式事务管理和基于@Transactional注解的使用
- spring事物配置,声明式事务管理和基于@Transactional注解的使用
- 基于注解的声明式事务管理
- spring事物配置,声明式事务管理和基于@Transactional注解的使用
- spring事物配置,声明式事务管理和基于@Transactional注解的使用
- spring事物配置,声明式事务管理和基于@Transactional注解的使用
- spring事物配置,声明式事务管理和基于@Transactional注解的使用
- spring事物配置,声明式事务管理和基于@Transactional注解的使用
- spring事物配置,声明式事务管理和基于@Transactional注解的使用