@Transactional注解回滚

1 创建一个实体类,该类拥有的属性与数据库拥有的字段一一对应

import lombok.Data;
@Data
public class InterfaceTest {
private Integer interfaceId;
private String interfaceName;
private String interfaceType;
private String interfaceMethod;
private String interfaceAliasName;

}

2 数据库表拥有的字段在这里插入图片描述
创建一个接口:写增删改查方法的接口,写入新增方法

import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface MyInterfaceTestMapper {
void addInterfaceTest(InterfaceTest interfaceTest);
}

创建一个xml文件:写增删改查sql的文件,写入新增sql

<mapper namespace="com.longteng.lesson2.my.mybatis.MyInterfaceTestMapper">
    <!--id就是接口中的方法名-->
    <insert id="addInterfaceTest"
            useGeneratedKeys="true"
            keyColumn="interface_test_id"
            keyProperty="interfaceId"
            parameterType="com.longteng.lesson2.my.mybatis.InterfaceTest">
            <!--给哪个表插入数据,就写哪个表-->
            insert into interface_test
            <!--给哪些字段插入数据,就写哪些字段名-->
            (interface_name,interface_method,interface_type,interface_alias_name)
            <!--要插入的数据是对应的哪些字段,就是实体类里的字段,要与字段名的先后顺序一一对应,用#{}接收-->
            values (#{interfaceName},#{interfaceMethod},#{interfaceType},#{interfaceAliasName})
    </insert>

事物:通过@Transactional进行事物回滚

多个操作放在一起执行叫事物
例如一个下订单的业务
最先执行的是插入数据库,但是插入数据库成功后,后续业务并没有成功,下订单业务还没有完全操作完毕,这个时候其实下订单已经失败了,那么插入数据的那条数据就是脏数据了,要做的就是对于事物没有成功的数据做回滚操作
事物分为编程事物管理、声明事物管理,例子中实现的是声明事物
编程事物:自己控制回滚流程,多用于复杂系统
声明事物:@Transactional注解控制回滚流程,多用于简单流程
import com.longteng.lesson2.my.mybatis.InterfaceTest;
import com.longteng.lesson2.my.mybatis.MyInterfaceTestMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class InterfaceService {
//注入接口
@Autowired
MyInterfaceTestMapper myInterfaceTestMapper;
//出现异常回滚
@Transactional(rollbackFor = Exception.class)
//返回Object类型的带参方法,抛出一个异常
public Object test(Integer i) throws Exception{
//创建实体类的实例,通过实例向数据库中添加数据
InterfaceTest interfaceTest=new InterfaceTest();
interfaceTest.setInterfaceName(“qwer”);
interfaceTest.setInterfaceMethod(“GET”);
interfaceTest.setInterfaceType(“HTTP”);
interfaceTest.setInterfaceAliasName(“QWER”);
//接口类实例调用接口的新增方法,添加数据到数据库
myInterfaceTestMapper.addInterfaceTest(interfaceTest);
//如果方法传参i不等于1就抛出异常,若等于1就正常返回,添加成功
if(i!=1){
throw new Exception();
}else {
return “添加成功”;
}
}
}

controller中

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class MyInterfaceController {
//注入回滚的业务类
@Autowired
InterfaceService interfaceService;
@RequestMapping("/interfaceService")
public @ResponseBody Object test(Integer i)throws Exception{
    return interfaceService.test(i);
}
}

浏览器请求 http://127.0.0.1:8080/interfaceService?i=1 i=1 添加数据到数据库成功

在这里插入图片描述
浏览器请求 http://127.0.0.1:8080/interfaceService?i=2 i=2 添加数据到数据库失败

如果不用@Transactional,就算请求时i不等于1插入数据库也能成功
例子中,调用addInterfaceTest方法其实就是插入数据库操作,并且debug的话,sql的确是打印了,但是这个时候并没有插入数据库,因为用了回滚的注解,整个事物是一次提交,不是代码读到哪里就执行哪里,是等test方法整个执行完毕,才确定该sql要不要插入数据库

猜你喜欢

转载自blog.csdn.net/qq_41767337/article/details/89397191