Spring 事务 注解@Transaction 用法

在实际开发中,对于一组数据库操作特别是增删改操作,为了保证原子性,通过需要用事务来控制,要么全部成功,要么全部失败。Spring中可以通过注解@Transaction

常用的方法如下:

 

@Transactional
public void testTransaction(User user) {
    int rowNum = userMapper.insertUser(user);
    List<User> userList = userMapper.selectAllUsers();
}

这里将两个操作insert和select当作原子操作,如果在testTransaction方法中有异常,则回滚。(注意:这个事务是MySQL层控制,回滚的操作也是MySQL控制的)。

需要注意的问题:

(1)尽可能将MySQL执行语句往方法体后面靠:

 

@Transactional
public void testTransaction(User user) {
    int rowNum = userMapper.insertUser(user);
    doSomething(); // 这个doSomthing 可能耗时较长
    List<User> userList = userMapper.selectAllUsers();
}

如果可以移动的话,可以将doSomething()可能耗时较长,移动到int rowNum=userMapper.insertUser(user)的前面,即:

@Transactional
public void testTransaction(User user) {
    doSomething(); // 这个doSomthing 可能耗时较长
    int rowNum = userMapper.insertUser(user);  
    List<User> userList = userMapper.selectAllUsers();
}

因为,MySQL事务的commit语句是在第一次执行MySQL相关语句开始,一直到方法的结束。

(2)设置事务的超时时间(如果不设置默认是-1是无限长)

 

@Transactional(timeout = 5)
public void testTransaction(User user) throws InterruptedException {
    Thread.sleep(2000);
    List<User> userList = userMapper.selectAllUsers(); // 耗时:1s
    int rowNum = userMapper.insertUser(user); // 耗时 1s
    Thread.sleep(3000);
}

加入另外两个MySQL相关的操作耗时都是1s,则上述事务是不会报超时异常。

timeout的计算的事务超时 = 最后一个MySQL语句耗时 + 以及最后一个MySQL之前的所有耗时。因此,上述耗时为2s+1s+1s=4s,没有超过5s,因此不会报事务超时异常,这个需要特别注意,如果想了解具体原理,可以查看源码,或者看该文档:http://jinnianshilongnian.iteye.com/blog/1986023

 

  • 4
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值