Spring 编程式事务和申明式事务选择和使用小结

1.选择编程式事务管理还是声明式事务管理:
    当你只有很少的事务操作时,编程式事务管理通常比较合适。例如,如果你有一个Web应用,其中只有特定的更新操作有事务要求,
你可能不愿使用Spring或其他技术设置事务代理。这种情况下,使用 TransactionTemplate 可能是个好办法。 
只有编程式事务管理才能显式的设置事务名称。 
    另一方面,如果你的应用中存在大量事务操作,那么声明式事务管理通常是值得的。它将事务管理与业务逻辑分离, 而且在Spring中配置也不难。
我们的开发中,一般使用到事务的地方比较少,我觉得,编程式事务足够了。
使用声明式事务,对我们这种对速度要求较高的应用中。反而会带来性能问题。

2:推荐事务处于一个较高层次,比如service上的某个函数(尤其是像我们这种sns而不像和钱挂钩的金融系统,对数据精确性要求不是很高的的应用),
而底层的dao可以不考虑事务(一般情况下,数据库自身的默认事务管理级别,就可以处理),否则可能会出现事务嵌套,增加程序复杂度。
事务往往和业务规紧密关联,当业务逻辑发生改变,意味着dao的大幅度改动。系统规模达到一定程度,修改风险相当大。
Spring事务的好处是不更改现有的dao,仅需对现有的service bean 进行配置或者尽量少的修改就达到事务效果了。
同时,把事务统一在service层,系统结构更清晰。

一般情况下,通常我们使用到事务的地方一般类似如下场景:
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
  protected void doInTransactionWithoutResult(TransactionStatus status) {
    try {
      updateOperation1();
      updateOperation2();
    } catch (SomeBusinessExeption ex) {
        //通过调用 TransactionStatus 对象的 setRollbackOnly() 方法来回滚事务。
      status.setRollbackOnly();
    }
  }
});

只有当两个操作updateOperation1(),updateOperation2() 同时成功时,才会提交事务,如果有一个操作失败,则事务回滚,保证数据的完整性。
达到了要么把事件都执行,要么都不执行的效果。

像我们现在使用的这种方式:
@Transactional
 public int insert(...) {}
@Transactional
 public int update(...) {}
我觉得可以不使用事务来保证它的正确性,”@Transactional“可以去除。
因为在dao层,而且操作都是针对数据库的单一操作,要么操作成功,要么操作失败,一般情况下,也不会出现数据不完整。

3 在代码中进行编程式事务管理:
首先在配置文件中添加如下两个bean,
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>    
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
    <property name="transactionManager" ref="transactionManager" />
</bean>

public class SimpleService implements Service {
private final TransactionTemplate transactionTemplate;
public void setTransactionTemplate(TransactionTemplate transactionTemplate){
    .....
}
.....
    //如果需要返回值:
    public Object someServiceMethod() {
        return transactionTemplate.execute(new TransactionCallback() {
          // the code in this method executes in a transactional context
          public Object doInTransaction(TransactionStatus status) {
            updateOperation1();
            return resultOfUpdateOperation2();
          }
        });
      }

    //如果不需要返回值:
    //回调方法内的代码可以通过调用 TransactionStatus 对象的 setRollbackOnly() 方法来回滚事务。
    transactionTemplate.execute(new TransactionCallbackWithoutResult() {
      protected void doInTransactionWithoutResult(TransactionStatus status) {
        try {
          updateOperation1();
          updateOperation2();
        } catch (SomeBusinessExeption ex) {
          status.setRollbackOnly();
        }
      }
    });
    //诸如传播模式、隔离等级、超时等等的事务设置都可以在TransactionTemplate中或者通过配置或者编程式地实现。如:
     transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
        transactionTemplate.setTimeout(30); // 30 seconds
    <bean id="sharedTransactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
          <property name="isolationLevelName" value="ISOLATION_READ_UNCOMMITTED"/>
          <property name="timeout" value="30"/>
         ......
    </bean>"

}

以上一定要注意,transactionTemplate 对应的数据源,一定要和updateOperation1();updateOperation2();操作对应的数据源相同。
如果不是同一个数据源,就需要JTA 来管理不同数据库之间的事务处理,情况就比较复杂了。

 4 Spring中事务是比较难理解的一部分,如果大家想了解诸如传播模式,隔离级别,脏读,幻读,不可重复读等等,推荐一篇文章:
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值