项目中必须用到的事务管理+spring事务管理

1.什么是事务?

  • 事务是由N步数据库操作序列组成的逻辑执行单元,这系列操作要么全部执行,要么全部都不执行。

2.事务的特性(ACID)

  • 原子性(Atomicity):事务是应用中不可再分的最小执行体
  • 一致性(Consistercy):事务执行的结果,须使数据从一个一致性状态,变为另一个一致性状态。
  • 隔离性(Isolation):各个事务的执行互不干扰,任何事务的内部操作对其他的事务都是隔离的。
  • 持久性(Durability):事务一旦提交,对数据所作的任何改变都要记录到永久存储器中。

3.事务的隔离性

  • 常见的并发异常
    • 第一类丢失更新、第二类丢失更新
    • 脏读、不可重复读、幻读
  • 常见的隔离级别
    • Read Unconmitted:读取未提交的数据
    • Read Committed:读取已提交的数据
    • Repeatable Read:可重复读
    • Serializable:串行化读

4.并发异常详解

  • 第一类丢失更新
    在这里插入图片描述

  • 第二类丢失更新

在这里插入图片描述

  • 脏读
    在这里插入图片描述

  • 不可重复读
    在这里插入图片描述

  • 幻读
    在这里插入图片描述

5.事务隔离级别具体解决什么问题?

在这里插入图片描述

6.隔离级别的实现机制?

  • 悲观锁(数据库)

    • 共享锁(S锁)
      • 事务A对某数据加了共享锁后,其它事务只能对该数据加共享锁,但不能加排他锁
    • 排他锁(X锁)
      • 事务A对某数据加了排他锁后,其它事务对该数据既不能加共享锁,也不能加排他锁。
  • 乐观锁(自定义)

    • 版本号、时间戳等
    • 在更新数据前,检查版本号是否发生变化,若变化则取消本次更新,否则就更新数据(版本号+1)

7.Spring事务管理

  • 声明式事务
    • 通过XML配置,声明某方法的事务特征
    • 通过注解,声明某方法的事务特征
  • 编程式事务
    • 通过TransactionTemplate管理事务,并通过它执行数据库的操作。

8.案例

  • 需求:在登陆成功之后自动发一个新人贴
  • 代码实现:(用上述的两种方式)
/**
     * 1.REQUIRED 支持当前事务(外部事务),如果不存在则创建新事务
     * 2.REQUIRES_NEW 创建一个新事务,并且暂停当前事务(外部事务)
     * 3.NESTED 如果存在事务(外部事务),则嵌套在该事务当中执行(但是有独立的提交和回滚),否则就会和REQUIRED效果一样
     * @return
     */
    @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
    public Object save1(){
        // 新增用户
        User user = new User();
        user.setUsername("alpha");
        user.setSalt(CommunityUtil.generateUUID().substring(0, 5));
        user.setPassword(CommunityUtil.md5("123" + user.getSalt()));
        user.setEmail("alpha@qq.com");
        user.setHeaderUrl("http://image/nowcoder.com/head/99t.png");
        user.setCreateTime(new Date());
        userMapper.insertUser(user);

        // 新增帖子
        DiscussPost post = new DiscussPost();
        post.setUserId(user.getId());
        post.setTitle("Hello!");
        post.setContent("新人报道!");
        post.setCreateTime(new Date());
        discussPostMapper.insertDiscussPost(post);

        // 造一个错
        Integer.valueOf("abc");

        return "ok";
    }

    public Object save2(){
        transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        return transactionTemplate.execute(new TransactionCallback<Object>() {
            @Override
            public Object doInTransaction(TransactionStatus status) {
                // 新增用户
                User user = new User();
                user.setUsername("beta");
                user.setSalt(CommunityUtil.generateUUID().substring(0, 5));
                user.setPassword(CommunityUtil.md5("123" + user.getSalt()));
                user.setEmail("beta@qq.com");
                user.setHeaderUrl("http://image/nowcoder.com/head/999t.png");
                user.setCreateTime(new Date());
                userMapper.insertUser(user);

                // 新增帖子
                DiscussPost post = new DiscussPost();
                post.setUserId(user.getId());
                post.setTitle("你好!");
                post.setContent("我是新人!");
                post.setCreateTime(new Date());
                discussPostMapper.insertDiscussPost(post);

                // 造一个错
                Integer.valueOf("abc");
                return "ok";
            }
        });
    }
  • 测试类:
public class TransactionTests {

    @Autowired
    private AlphaService alphaService;

    @Test
    public void testSave1(){
        Object obj = alphaService.save1();
        System.out.println(obj);
    }

    @Test
    public void testSave2(){
        Object obj = alphaService.save2();
        System.out.println(obj);
    }
}

  • 运行结果
    在这里插入图片描述
  • 并且数据库的两张表都没有数据添加。保证了事务的特性。
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值