Spring @transactional annotation 事务使用详解

【转自】 http://www.yihaomen.com/article/java/412.htm

annotation 方式写程序越来越称谓主流了,以前用hibernate 也用 xml 一大堆配置文件。spring beans 管理也是一大堆xml 配置文件,但现在的趋势是 annotation ,这种方式写程序更方便,很少配置文件,维护起来也比较方便。这几天重新看 spring 的文档,仔细看了下 annotation 方式下事务的管理方式.
1. 配置 <context:annotation-config/>: 告诉spring 去读 @Transactional 标注
2. <tx:annotation-driven/>:  自动包装代码,生产事务管理
3. 初始化 Datasource TransactionManager bean.
程序代码 程序代码

<context:annotation-config/>
<!-- Add this tag to enable annotations transactions -->
<tx:annotation-driven  transaction-manager="transactionManager"/>
<bean id="transactionManager"
  class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="dataSource"></property>
</bean>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
  <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  <property name="url" value="jdbc:mysql://localhost:3306/apu"></property>
  <property name="username" value="root"></property>
  <property name="password" value=""></property>
  <!--改成你的密码-->
</bean>
    
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
  <property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="userDao"   class="springjdbc.transactions.declarative.annotations.AnnotatedUserDao">
  <property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>


如果 @Transactional 标注在 Class 上面, 那么将会对这个 Class 里面所有的 public 方法都包装事务方法. 它有几个属性是可以配置的  readOnly, isolation, propagation,rollbackFor, noRollbackFor 。如果标记 readOnly=true, 那么就只能选择了,因为只有查询语句才能执行,如果是insert,update,delete 等,应该是readOnly=false, 不过默认是false的。rollbackFor 和 noRollbackFor 也是比较重要的两个属性. 默认情况下在有异常 RuntimeException  抛出或者 unchecked 异常抛出时,会回滚.

借用官方的例子:
程序代码 程序代码

@Transactional
public class AnnotatedUserDao implements IUserDao {
private JdbcTemplate jdbcTemplate;

public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
  this.jdbcTemplate = jdbcTemplate;
}
    
public void deleteUser(int uid) {
  String delQuery = "delete from users where id = ?";
  jdbcTemplate.update(delQuery, new Object[] { uid });

}

public int insertUser(User user) {
  String inserQuery = "insert into users (username, password, enabled , id) values (?, ?, ?, ?) ";
  Object[] params = new Object[] { user.getUserName(),
                user.getPassword(), user.isEnabled(), user.getId() };
  int[] types = new int[] { Types.VARCHAR, Types.VARCHAR, Types.BIT,
                Types.INTEGER };
  int number = jdbcTemplate.update(inserQuery, params, types);
  return number;
}

// override the class level transactional behaviour for select method
@Transactional(readOnly = true)
public User selectUser(int uid) {
// for all the RuntimeExceptions the transactions will be automatically
// rolled back
  throw new RuntimeException("A runtime exception");

}

public int updateUser(User user) throws Exception {
  throw new Exception("A checked exception");
}


selectUser 会回滚,因为抛出了 RuntimeException 异常,而 updateUser 会执行下去,并不回滚,因为抛出的是 A checked exception .


原理:  其实就是利用 AOP , spring 生成了一个代理类 这个代理类加入了事务的控制来实现。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值