Spring中Transactional注解的使用详解和实例

24 篇文章 0 订阅

Spring中Transactional注解的使用:

    @Transactional(propagation=Propagation.REQUIRED,rollbackFor = Exception.class) 已经有事务则直接加入,没有事务则新建事务;遇到异常则回滚

1)定义事物传播行为介绍:

  @Transactional(propagation=Propagation.REQUIRED) :如果有事务, 那么加入事务, 没有的话新建一个(默认情况下)                 @Transactional(propagation=Propagation.REQUIRES_NEW) :不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务

  @Transactional(propagation=Propagation.MANDATORY) :必须在一个已有的事务中执行,否则抛出异常

  @Transactional(propagation=Propagation.NEVER) :必须在一个没有的事务中执行,否则抛出异常(与Propagation.MANDATORY相反)

  @Transactional(propagation=Propagation.SUPPORTS) :如果其他bean调用这个方法,在其他bean中声明事务,那就用事务.如果其他bean没有声明事务,那就不用事务.

@Transactional(propagation=Propagation.NOT_SUPPORTED) :容器不为这个方法开启事务

2)事物超时设置:

@Transactional(timeout=30) //默认是30秒

3)事务隔离级别:

  @Transactional(isolation = Isolation.READ_UNCOMMITTED):读取未提交数据(会出现脏读, 不可重复读) 基本不使用

  @Transactional(isolation = Isolation.READ_COMMITTED):读取已提交数据(会出现不可重复读和幻读)

  @Transactional(isolation = Isolation.REPEATABLE_READ):可重复读(会出现幻读)

  @Transactional(isolation = Isolation.SERIALIZABLE):串行化

 MYSQL: 默认为REPEATABLE_READ级别

  SQLSERVER: 默认为READ_COMMITTED

4)定义事物遇到哪些异常会回滚(rollback)

在Spring中,@Transactional默认遇到运行时异常(RuntimeException)和错误(Error)时会回滚事务。具体来说,当方法抛出任何继承自RuntimeException的异常或Error时,Spring会自动回滚事务。如果抛出的是checked异常(非RuntimeException),则默认情况下不会回滚事务,需要使用rollbackFor属性指定需要回滚的异常类型。

在Java中,异常分为两种类型:checked异常和unchecked异常。

Checked异常是指在编译时必须处理的异常,即在方法声明中必须声明或捕获的异常。例如,IOException、SQLException等都是checked异常。如果不处理这些异常,编译器会报错。

Unchecked异常是指在编译时不需要处理的异常,即不需要在方法声明中声明或捕获的异常。例如,NullPointerException、ArrayIndexOutOfBoundsException等都是unchecked异常。如果不处理这些异常,程序会在运行时抛出异常。

通常情况下,我们应该尽可能地使用checked异常,因为它们可以提醒程序员在编写代码时必须考虑异常情况,从而编写更加健壮的代码。而unchecked异常则通常是由程序员的错误导致的,应该尽可能避免出现这种异常。

5)使用注意点

a @Transactional 注解应该只被应用到 public 可见度的方法上。 如果你在 protected、private 或者 package-visible 的方法上使用 @Transactional 注解,它也不会报错, 但是这个被注解的方法将不会展示已配置的事务设置。

b 如果方法save中使用了事务,但是方法get被声明了不支持事务,在方法save中调用了方法get,此时会出现save中插入的记录在get中查询不到。不允许支持事务的配置可能如下:

 

spring @Transactional注解参数详解 - Just_Do - 博客园

Ssm框架下使用数据库的事物:

首先确认数据库的引擎类型,如果是myisam则不支持使用事物,修改为InnoDB支持事物.

show engines;//查看数据库引擎 类型

alter table task_baseinfo type=innodb;//修改task_baseinfo引擎类型为innodb

  1. spring的配置文件中 声明 和 开启 事物管理

        <!-- 开启事物管理 -->

    <tx:annotation-driven transaction-manager="transactionManager"/>

    <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->

    <bean id="transactionManager"

        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

        <property name="dataSource" ref="dynamicDataSource" />

    </bean>

2)对公共方法增加事物管理

//  @Transactional(readOnly=false,propagation=Propagation.REQUIRED,rollbackFor = Exception.class)

    @Transactional

    @Override

    public int saveTaskBaseInfo(int taskId, String taskName, int taskType,

           int funcNum, String lastModifiedUser,String allbefroeTaskId, String startDate,int startTime,int endTime)  {

           // 如果任务中包含有 taskId则执行修改

           //新插入执行的操作

           int newTaskId=getMaxTaskId()+1;

           taskId = newTaskId   ;

           HashMap<String, Object> map = new HashMap<String, Object>();

           map.put("table_name", "task_baseinfo");

           map.put("col_name", "task_id,task_name,task_type,create_time,last_modified_user,isdel");

           map.put("col_value", "("+newTaskId+",'"+taskName+"',"+taskType+",'"+DateUtil.getNowDateAsStr()+"','"+lastModifiedUser+"'"+",0"+")");

           mysqlAlterService.addRecord(map);//第一个插入操作

          

       int recode=taskTimeInfoService.insertTaskTimeInfo(taskId, startDate, startTime, endTime);//第二个插入操作,如果插入有问题,则返回的值为负数

              if(recode<0){

                  throw new RuntimeException("该任务的定时信息插入失败...");//此处抛出的RuntimeException十分重要,只有抛出了该异常才会调用事物管理,此时抛出运行时异常说明第二个插入有问题.所以两个插入均失败;虽然第一个插入操作已经执行,但是此时会自动回滚.

              }

       return 1000;

    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值