>  기사  >  Java  >  SpringBoot 트랜잭션 관리 사례 분석

SpringBoot 트랜잭션 관리 사례 분석

WBOY
WBOY앞으로
2023-05-13 14:13:20578검색

1. 트랜잭션의 정의

트랜잭션은 일련의 N단계 데이터베이스 작업으로 구성된 논리적 실행 단위입니다. 이 일련의 작업은 모두 실행되거나 모두 중단됩니다.

2. 트랜잭션의 특성

트랜잭션의 특성: ACID

  • 원자성: 트랜잭션은 애플리케이션에서 분할할 수 없는 가장 작은 실행 본체입니다.

  • 일관성: 트랜잭션 실행의 결과는 일관된 상태에서 데이터를 변경해야 합니다. 다른 일관성 상태로

  • 격리: 각 트랜잭션의 실행은 서로 간섭하지 않으며 모든 트랜잭션의 내부 작업은 다른 트랜잭션과 격리됩니다.

  • 지속성: 트랜잭션이 제출되면 수행되는 작업 데이터의 모든 수정 사항은 영구 저장소에 기록되어야 합니다

3. 트랜잭션 격리

일반적인 동시성 예외

  • 첫 번째 유형의 업데이트 손실, 두 번째 유형의 업데이트 손실

  • 더티 읽기, 반복 불가능 읽기, 팬텀 읽기

공통 격리 수준

  • 커밋되지 않은 읽기: 커밋되지 않은 데이터 읽기

  • 커밋된 읽기: 제출된 데이터 읽기

  • 반복 읽기: 반복 읽기

  • 직렬 가능: 직렬화

업데이트 손실의 첫 번째 유형: 트랜잭션 롤백으로 인해 다른 트랜잭션에서 업데이트된 데이터가 손실됩니다.

두 번째 유형의 업데이트 손실: 특정 거래를 제출하면 다른 거래에서 업데이트된 데이터가 손실됩니다.

더티 읽기: 특정 트랜잭션이 다른 트랜잭션에서 커밋되지 않은 데이터를 읽습니다.

비반복 읽기: 특정 트랜잭션이 이전과 이후에 동일한 데이터를 읽는 결과가 일치하지 않습니다.

환상 읽기: 특정 트랜잭션의 경우 동일한 테이블 전후에 쿼리되는 행 수가 일치하지 않습니다.

격리 수준업데이트 손실의 첫 번째 유형더티 읽기업데이트 손실의 두 번째 유형반복 불가능한 읽기팬텀 읽기커밋되지 않은 읽기 예 예 예예예읽기 커밋됨NoNo예예예반복 읽기아니요아니요 아니요아니요예 공유 잠금(S 잠금) : 트랜잭션 A가 특정 데이터에 공유 잠금을 추가한 후 다른 트랜잭션은 해당 데이터에 공유 잠금을 추가할 수만 있고 배타적 잠금은 추가할 수 없습니다배타적 잠금(X 잠금) : 트랜잭션 A가 특정 데이터에 배타적 잠금을 추가한 후에는 다른 트랜잭션이 이 데이터에 공유 잠금이나 배타적 잠금을 추가할 수 없습니다. 낙관적 잠금(맞춤형) 버전 번호, 타임스탬프 등 데이터를 업데이트하기 전에 버전 번호가 변경되었는지 확인하세요. 변경사항이 발생하면 이 업데이트를 취소하고 그렇지 않으면 데이터를 업데이트합니다(버전 번호 +1)
아니요

Spring 트랜잭션 관리

선언적 트랜잭션

  • XML 구성을 통해 메소드의 트랜잭션 특성을 선언합니다.

  • 애노테이션을 통해 메소드의 트랜잭션 특성을 선언합니다.

프로그래밍 방식 트랜잭션

  • TransactionTemplate을 통해 트랜잭션을 관리하고 이를 통해 데이터베이스 작업을 수행합니다.

  • 5. 예

    package com.nowcoder.community.service;
    import com.nowcoder.community.dao.AlphaDao;
    import com.nowcoder.community.dao.DiscussPostMapper;
    import com.nowcoder.community.dao.UserMapper;
    import com.nowcoder.community.entity.DiscussPost;
    import com.nowcoder.community.entity.User;
    import com.nowcoder.community.util.CommunityUtil;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Scope;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.TransactionDefinition;
    import org.springframework.transaction.TransactionStatus;
    import org.springframework.transaction.annotation.Isolation;
    import org.springframework.transaction.annotation.Propagation;
    import org.springframework.transaction.annotation.Transactional;
    import org.springframework.transaction.support.TransactionCallback;
    import org.springframework.transaction.support.TransactionTemplate;
    import javax.annotation.PostConstruct;
    import javax.annotation.PreDestroy;
    import java.util.Date;
    @Service
    //@Scope("prototype")
    public class AlphaService {
        @Autowired
        private AlphaDao alphaDao;
        @Autowired
        private UserMapper userMapper;
        @Autowired
        private DiscussPostMapper discussPostMapper;
        @Autowired
        private TransactionTemplate transactionTemplate;
        public AlphaService() {
    //        System.out.println("实例化AlphaService");
        }
        @PostConstruct
        public void init() {
    //        System.out.println("初始化AlphaService");
        }
        @PreDestroy
        public void destroy() {
    //        System.out.println("销毁AlphaService");
        }
        public String find() {
            return alphaDao.select();
        }
        // REQUIRED: 支持当前事务(外部事务),如果不存在则创建新事务.
        // REQUIRES_NEW: 创建一个新事务,并且暂停当前事务(外部事务).
        // NESTED: 如果当前存在事务(外部事务),则嵌套在该事务中执行(独立的提交和回滚),否则就会REQUIRED一样.
        @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("https://cache.yisu.com/upload/information/20220823/112/6198.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("https://cache.yisu.com/upload/information/20220823/112/6199.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";
                }
            });
        }
    }

위 내용은 SpringBoot 트랜잭션 관리 사례 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제