Spring 之注解事务 @Transactional
来源:互联网 发布:含钢量计算软件 编辑:程序博客网 时间:2024/05/16 05:45
先让我们看代码吧!
以下代码为在“Spring3事务管理——基于tx/aop命名空间的配置”基础上修改。首先修改applicationContext.xml如下:
<!-- 定义一个数据源 --><bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/spring_test" /> <property name="username" value="root" /> <property name="password" value="root" /></bean> <!-- 定义JdbcTemplate的Bean --><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" p:dataSource-ref="dataSource"></bean> <!-- 配置事务管理器 --><bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSource"></bean> <!-- enables scanning for @Transactional annotations --><tx:annotation-driven transaction-manager="txManager" /> <!-- 在该Bean的代码中标注@Transactional可以被事务管理器注入 --><bean id="userScore" class="net.hingyi.springDemo.transaction.service.UserScoreServiceImpl" p:userScoreRepository-ref="userScoreRepository_jdbc" /> <bean id="userScoreRepository_jdbc" class="net.hingyi.springDemo.transaction.repository.UserScoreRepositoryImpl" p:jdbcTemplate-ref="jdbcTemplate" />
实现类代码:
@Transactional
public
class
UserScoreRepositoryImpl
implements
UserScoreRepository {
private
JdbcTemplate jdbcTemplate;
@Override
public
UserScore getUserSocore(String userNo) {
final
UserScore us =
new
UserScore();
...
return
us;
}
...
}
OK了!以上就实现了简单的事务管理了。现在再稍微了解下@Transactional。
在配置文件中,默认情况下,<tx:annotation-driven>会自动使用名称为transactionManager的事务管理器。所以,如果定义的事务管理器名称为transactionManager,那么就可以直接使用<tx:annotation-driven/>。如下:
<!-- 配置事务管理器 -->
<
bean
id
=
"transactionManager"
class
=
"org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref
=
"dataSource"
>
</
bean
>
<!-- enables scanning for @Transactional annotations -->
<
tx:annotation-driven
/>
<tx:annotation-driven>一共有四个属性如下,
- mode:指定Spring事务管理框架创建通知bean的方式。可用的值有proxy和aspectj。前者是默认值,表示通知对象是个JDK代理;后者表示Spring AOP会使用AspectJ创建代理
- proxy-target-class:如果为true,Spring将创建子类来代理业务类;如果为false,则使用基于接口的代理。(如果使用子类代理,需要在类路径中添加CGLib.jar类库)
- order:如果业务类除事务切面外,还需要织入其他的切面,通过该属性可以控制事务切面在目标连接点的织入顺序。
- transaction-manager:指定到现有的PlatformTransaction Manager bean的引用,通知会使用该引用
@Transactional的属性
属性名
类型
说明
isolation
枚举org.springframework.transaction.annotation.Isolation的值
事务隔离级别
noRollbackFor
Class<? extends Throwable>[]
一组异常类,遇到时不回滚。默认为{}
noRollbackForClassName
Stirng[]
一组异常类名,遇到时不回滚,默认为{}
propagation
枚举org.springframework.transaction.annotation.Propagation的值
事务传播行为
readOnly
boolean
事务读写性
rollbackFor
Class<? extends Throwable>[]
一组异常类,遇到时回滚
rollbackForClassName
Stirng[]
一组异常类名,遇到时回滚
timeout
int
超时时间,以秒为单位
value
String
可选的限定描述符,指定使用的事务管理器
@Transactional标注的位置
@Transactional注解可以标注在类和方法上,也可以标注在定义的接口和接口方法上。
如果我们在接口上标注@Transactional注解,会留下这样的隐患:因为注解不能被继承,所以业务接口中标注的@Transactional注解不会被业务实现类继承。所以可能会出现不启动事务的情况。所以,Spring建议我们将@Transaction注解在实现类上。
在方法上的@Transactional注解会覆盖掉类上的@Transactional。
使用不同的事务管理器
如果我们要程序中使用多个事务管理器(主要是针对多数据源的情况),可以通过以下的方式实现:
Service代码:
public
class
MultiTxService {
@Transactional
(
"tran_1"
)
public
void
addTest(
int
id){
}
@Transactional
(
"tran_2"
)
public
void
deleteTest(
int
id){
}
}
applicationContext.xml配置如下:
<
bean
id
=
"tran_1"
class
=
"org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref
=
"dataSource"
>
<
qualifier
value
=
"tran_1"
/>
</
bean
>
<
bean
id
=
"tran_2"
class
=
"org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref
=
"dataSource"
>
<
qualifier
value
=
"tran_2"
/>
</
bean
>
经过以上的代码,每个事务都会绑定各自的独立的数据源,进行各自的事务管理。我们可以优化下以上代码,可以自定义一个绑定到特定事务管理器的注解,然后直接使用这个自定义的注解进行标识:
@Target
({ElementType.METHOD,ElementType.TYPE})
@Retention
(RetentionPolicy.RUNTIME)
@Transactional
(
"tran_1"
)
public
@interface
CustomerTransactional {
}
在Service代码中使用:
...
//使用名为tran_1的事务管理器
@CustomerTransactional
public void addTest(String str){
}
…
Spring在TransactionDefinition接口中规定了7种类型的事务传播行为,
它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播:
事务传播行为类型
事务传播行为类型
说明
PROPAGATION_REQUIRED
如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
PROPAGATION_SUPPORTS
支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY
使用当前的事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW
新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER
以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类 似的操作。
spring 事务注解默认遇到throw new RuntimeException("...");会回滚需要捕获的throw new Exception("...");不会回滚// 指定回滚@Transactional(rollbackFor=Exception.class) public void methodName() { // 不会回滚 throw new Exception("..."); } //指定不回滚@Transactional(noRollbackFor=Exception.class) public ItimDaoImpl getItemDaoImpl() { // 会回滚 throw new RuntimeException("注释"); } // 如果有事务,那么加入事务,没有的话新建一个(不写的情况下) @Transactional(propagation=Propagation.REQUIRED) // 容器不为这个方法开启事务 @Transactional(propagation=Propagation.NOT_SUPPORTED) // 不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务 @Transactional(propagation=Propagation.REQUIRES_NEW) // 必须在一个已有的事务中执行,否则抛出异常 @Transactional(propagation=Propagation.MANDATORY) // 必须在一个没有的事务中执行,否则抛出异常(与Propagation.MANDATORY相反) @Transactional(propagation=Propagation.NEVER) // 如果其他bean调用这个方法,在其他bean中声明事务,那就用事务.如果其他bean没有声明事务,那就不用事务. @Transactional(propagation=Propagation.SUPPORTS) /* public void methodName(){ // 本类的修改方法 1 update(); // 调用其他类的修改方法 otherBean.update(); // 本类的修改方法 2 update(); } other失败了不会影响 本类的修改提交成功 本类update的失败,other也失败 */@Transactional(propagation=Propagation.NESTED) // readOnly=true只读,能插入,但不能更新,删除 @Transactional (propagation = Propagation.REQUIRED,readOnly=true) // 设置超时时间@Transactional (propagation = Propagation.REQUIRED,timeout=30)// 设置数据库隔离级别@Transactional (propagation = Propagation.REQUIRED,isolation=Isolation.DEFAULT)
- 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
- Spring 之注解事务 @Transactional
- ffmpeg 常用命令(转)
- Objective-C对象初始化小结
- <转载>深入java垃圾回收的详解
- Android事件分发机制总结
- 算法导论-快速排序
- Spring 之注解事务 @Transactional
- iOS UDP编程
- 贪心+map Codeforces583C GCD Table
- Hadoop集群虚拟机网卡的介绍和配置
- ios9 qq微信微博等分享用不了的解决方案
- UDP TCP区别
- 安装Docker
- 转义符
- C++实现稀疏矩阵的十字链表表示法